]> git.openstreetmap.org Git - rails.git/commitdiff
Merge remote-tracking branch 'openstreetmap/pull/1344'
authorTom Hughes <tom@compton.nu>
Thu, 27 Oct 2016 10:51:36 +0000 (11:51 +0100)
committerTom Hughes <tom@compton.nu>
Thu, 27 Oct 2016 10:51:36 +0000 (11:51 +0100)
332 files changed:
.rubocop.yml
.rubocop_todo.yml
.travis.yml
Gemfile
Gemfile.lock
INSTALL.md
README.md
Vendorfile
app/assets/images/banners/.keep [new file with mode: 0644]
app/assets/images/banners/donate-2016.jpg [new file with mode: 0644]
app/assets/images/banners/sotmasia-2016.jpg [new file with mode: 0644]
app/assets/images/banners/sotmlatam-2016.jpg [new file with mode: 0644]
app/assets/images/github.png [new file with mode: 0644]
app/assets/images/key/cyclemap/bicycle_parking.png [new file with mode: 0644]
app/assets/images/key/cyclemap/bicycle_shop.png [new file with mode: 0644]
app/assets/images/key/cyclemap/common.png [new file with mode: 0644]
app/assets/images/key/cyclemap/cycleway.png [new file with mode: 0644]
app/assets/images/key/cyclemap/cycleway_local.png [new file with mode: 0644]
app/assets/images/key/cyclemap/cycleway_local13.png [new file with mode: 0644]
app/assets/images/key/cyclemap/cycleway_national.png [new file with mode: 0644]
app/assets/images/key/cyclemap/cycleway_national13.png [new file with mode: 0644]
app/assets/images/key/cyclemap/cycleway_regional.png [new file with mode: 0644]
app/assets/images/key/cyclemap/cycleway_regional13.png [new file with mode: 0644]
app/assets/images/key/cyclemap/footway.png [new file with mode: 0644]
app/assets/images/key/cyclemap/forest.png [new file with mode: 0644]
app/assets/images/key/cyclemap/lake.png [new file with mode: 0644]
app/assets/images/key/cyclemap/motorway.png [new file with mode: 0644]
app/assets/images/key/cyclemap/motorway12.png [new file with mode: 0644]
app/assets/images/key/cyclemap/primary.png [new file with mode: 0644]
app/assets/images/key/cyclemap/primary12.png [new file with mode: 0644]
app/assets/images/key/cyclemap/rail.png [new file with mode: 0644]
app/assets/images/key/cyclemap/rail14.png [new file with mode: 0644]
app/assets/images/key/cyclemap/secondary.png [new file with mode: 0644]
app/assets/images/key/cyclemap/secondary12.png [new file with mode: 0644]
app/assets/images/key/cyclemap/toilets.png [new file with mode: 0644]
app/assets/images/key/cyclemap/track.png [new file with mode: 0644]
app/assets/images/key/cyclemap/trunk.png [new file with mode: 0644]
app/assets/images/key/cyclemap/trunk12.png [new file with mode: 0644]
app/assets/images/routing-sprite.png
app/assets/images/routing-sprite.svg [new file with mode: 0644]
app/assets/images/wordpress.png
app/assets/javascripts/embed.js.erb
app/assets/javascripts/index.js
app/assets/javascripts/index/directions/graphhopper.js
app/assets/javascripts/index/directions/mapquest.js
app/assets/javascripts/index/directions/mapzen.js
app/assets/javascripts/index/directions/osrm.js
app/assets/javascripts/index/search.js
app/assets/javascripts/leaflet.key.js
app/assets/javascripts/leaflet.layers.js
app/assets/javascripts/leaflet.map.js
app/assets/javascripts/osm.js.erb
app/assets/javascripts/user.js
app/assets/stylesheets/common.scss
app/assets/stylesheets/small.scss
app/controllers/amf_controller.rb
app/controllers/api_controller.rb
app/controllers/application_controller.rb
app/controllers/changeset_controller.rb
app/controllers/diary_entry_controller.rb
app/controllers/geocoder_controller.rb
app/controllers/message_controller.rb
app/controllers/notes_controller.rb
app/controllers/oauth_controller.rb
app/controllers/swf_controller.rb
app/controllers/trace_controller.rb
app/controllers/user_controller.rb
app/controllers/user_preference_controller.rb
app/helpers/banner_helper.rb [new file with mode: 0644]
app/helpers/browse_helper.rb
app/helpers/note_helper.rb
app/helpers/trace_helper.rb
app/models/acl.rb
app/models/client_application.rb
app/models/diary_entry.rb
app/models/diary_entry_subscription.rb [new file with mode: 0644]
app/models/node.rb
app/models/notifier.rb
app/models/relation.rb
app/models/trace.rb
app/models/user.rb
app/models/way.rb
app/views/api/permissions.builder
app/views/changeset/_comments.rss.builder
app/views/changeset/comments_feed.rss.builder
app/views/changeset/list.atom.builder
app/views/changeset/timeout.atom.builder
app/views/diary_entry/rss.rss.builder
app/views/diary_entry/view.html.erb
app/views/layouts/_banner.html.erb [new file with mode: 0644]
app/views/layouts/map.html.erb
app/views/notes/_note.gpx.builder
app/views/notes/_note.rss.builder
app/views/notes/_note.xml.builder
app/views/notes/feed.rss.builder
app/views/notes/index.gpx.builder
app/views/notes/index.rss.builder
app/views/notes/show.gpx.builder
app/views/notes/show.rss.builder
app/views/trace/georss.rss.builder
app/views/user/api_read.builder
app/views/user/login.html.erb
config/banners.yml [new file with mode: 0644]
config/example.application.yml
config/initializers/assets.rb
config/initializers/banners.rb [new file with mode: 0644]
config/initializers/omniauth.rb
config/initializers/paperclip.rb
config/initializers/r2.rb
config/key.yml
config/locales/ar.yml
config/locales/ast.yml
config/locales/bn.yml [new file with mode: 0644]
config/locales/br.yml
config/locales/ca.yml
config/locales/cs.yml
config/locales/da.yml
config/locales/de.yml
config/locales/diq.yml
config/locales/dsb.yml
config/locales/el.yml
config/locales/en-GB.yml
config/locales/en.yml
config/locales/eo.yml
config/locales/es.yml
config/locales/et.yml
config/locales/fi.yml
config/locales/fr.yml
config/locales/gd.yml
config/locales/gl.yml
config/locales/he.yml
config/locales/hsb.yml
config/locales/hu.yml
config/locales/ia.yml
config/locales/id.yml
config/locales/it.yml
config/locales/ja.yml
config/locales/ka.yml
config/locales/ko.yml
config/locales/lb.yml
config/locales/lt.yml
config/locales/lv.yml
config/locales/mk.yml
config/locales/mr.yml
config/locales/ms.yml
config/locales/nb.yml
config/locales/nl.yml
config/locales/nn.yml
config/locales/oc.yml
config/locales/pa.yml
config/locales/pl.yml
config/locales/pt-BR.yml
config/locales/pt-PT.yml
config/locales/ro.yml
config/locales/ru.yml
config/locales/sl.yml
config/locales/sq.yml
config/locales/sr-Latn.yml
config/locales/sr.yml
config/locales/sv.yml
config/locales/te.yml
config/locales/tl.yml
config/locales/tr.yml
config/locales/uk.yml
config/locales/vi.yml
config/locales/zh-CN.yml
config/locales/zh-TW.yml
config/routes.rb
db/functions/Makefile
db/migrate/008_remove_segments.rb
db/migrate/020_populate_node_tags_and_remove.rb
db/migrate/021_move_to_innodb.rb
db/migrate/20150818224516_set_default_gravatar_to_false_for_privacy.rb [new file with mode: 0644]
db/migrate/20161002153425_add_join_table_between_users_and_diary_entries.rb [new file with mode: 0644]
db/migrate/20161011010929_subscribe_authors_to_diary_entries.rb [new file with mode: 0644]
db/structure.sql
lib/auth.rb
lib/bounding_box.rb
lib/classic_pagination/pagination.rb
lib/country.rb
lib/daemons/gpx_import_ctl
lib/id.rb
lib/migrate.rb
lib/osm.rb
lib/potlatch.rb
lib/quova.rb [deleted file]
script/gravatar [new file with mode: 0755]
test/controllers/amf_controller_test.rb
test/controllers/api_controller_test.rb
test/controllers/browse_controller_test.rb
test/controllers/changeset_controller_test.rb
test/controllers/diary_entry_controller_test.rb
test/controllers/geocoder_controller_test.rb
test/controllers/message_controller_test.rb
test/controllers/notes_controller_test.rb
test/controllers/oauth_clients_controller_test.rb
test/controllers/redactions_controller_test.rb
test/controllers/relation_controller_test.rb
test/controllers/site_controller_test.rb
test/controllers/trace_controller_test.rb
test/controllers/user_blocks_controller_test.rb
test/controllers/user_controller_test.rb
test/controllers/user_preference_controller_test.rb
test/controllers/way_controller_test.rb
test/factories/acls.rb [new file with mode: 0644]
test/factories/changeset_comments.rb [new file with mode: 0644]
test/factories/diary_comments.rb [new file with mode: 0644]
test/factories/diary_entries.rb [new file with mode: 0644]
test/factories/friends.rb [new file with mode: 0644]
test/factories/languages.rb [new file with mode: 0644]
test/factories/messages.rb [new file with mode: 0644]
test/factories/note_comments.rb [new file with mode: 0644]
test/factories/notes.rb [new file with mode: 0644]
test/factories/user_blocks.rb [new file with mode: 0644]
test/factories/user_preferences.rb [new file with mode: 0644]
test/fixtures/acls.yml [deleted file]
test/fixtures/changeset_comments.yml [deleted file]
test/fixtures/countries.yml [deleted file]
test/fixtures/diary_comments.yml [deleted file]
test/fixtures/diary_entries.yml [deleted file]
test/fixtures/friends.yml [deleted file]
test/fixtures/languages.yml [deleted file]
test/fixtures/messages.yml [deleted file]
test/fixtures/note_comments.yml [deleted file]
test/fixtures/notes.yml [deleted file]
test/fixtures/user_blocks.yml [deleted file]
test/fixtures/user_preferences.yml [deleted file]
test/fixtures/users.yml
test/helpers/browse_helper_test.rb
test/http/geocoder_ca.yml
test/http/geocoder_us.yml
test/http/geonames.yml
test/http/gravatar.yml [new file with mode: 0644]
test/http/nominatim.yml
test/http/npemap.yml
test/integration/oauth_test.rb
test/integration/user_blocks_test.rb
test/integration/user_changeset_comments_test.rb
test/integration/user_creation_test.rb
test/integration/user_diaries_test.rb
test/integration/user_login_test.rb
test/lib/bounding_box_test.rb
test/lib/country_test.rb
test/lib/i18n_test.rb
test/lib/locale_test.rb
test/models/acl_test.rb
test/models/changeset_comment_test.rb
test/models/diary_comment_test.rb
test/models/diary_entry_test.rb
test/models/friend_test.rb
test/models/language_test.rb
test/models/message_test.rb
test/models/note_comment_test.rb
test/models/note_test.rb
test/models/user_preference_test.rb
test/models/user_test.rb
test/test_helper.rb
vendor/assets/iD/iD.css.erb
vendor/assets/iD/iD.js
vendor/assets/iD/iD/img/iD-sprite.svg
vendor/assets/iD/iD/locales/af.json
vendor/assets/iD/iD/locales/ar-AA.json
vendor/assets/iD/iD/locales/ar.json
vendor/assets/iD/iD/locales/ast.json
vendor/assets/iD/iD/locales/bg-BG.json
vendor/assets/iD/iD/locales/bn.json
vendor/assets/iD/iD/locales/bs.json
vendor/assets/iD/iD/locales/ca.json
vendor/assets/iD/iD/locales/cs.json
vendor/assets/iD/iD/locales/da.json
vendor/assets/iD/iD/locales/de.json
vendor/assets/iD/iD/locales/el.json
vendor/assets/iD/iD/locales/en-GB.json
vendor/assets/iD/iD/locales/en.json
vendor/assets/iD/iD/locales/es.json
vendor/assets/iD/iD/locales/et.json
vendor/assets/iD/iD/locales/fa.json
vendor/assets/iD/iD/locales/fi.json
vendor/assets/iD/iD/locales/fil.json [deleted file]
vendor/assets/iD/iD/locales/fr.json
vendor/assets/iD/iD/locales/gl.json
vendor/assets/iD/iD/locales/gu.json [new file with mode: 0644]
vendor/assets/iD/iD/locales/hr.json
vendor/assets/iD/iD/locales/hu.json
vendor/assets/iD/iD/locales/hy.json
vendor/assets/iD/iD/locales/id.json
vendor/assets/iD/iD/locales/is.json
vendor/assets/iD/iD/locales/it.json
vendor/assets/iD/iD/locales/ja.json
vendor/assets/iD/iD/locales/kn.json
vendor/assets/iD/iD/locales/ko-KR.json [deleted file]
vendor/assets/iD/iD/locales/ko.json
vendor/assets/iD/iD/locales/lt.json
vendor/assets/iD/iD/locales/lv.json
vendor/assets/iD/iD/locales/ml.json [new file with mode: 0644]
vendor/assets/iD/iD/locales/nl.json
vendor/assets/iD/iD/locales/no.json
vendor/assets/iD/iD/locales/pl.json
vendor/assets/iD/iD/locales/pt-BR.json
vendor/assets/iD/iD/locales/pt.json
vendor/assets/iD/iD/locales/ro.json
vendor/assets/iD/iD/locales/ru.json
vendor/assets/iD/iD/locales/si.json
vendor/assets/iD/iD/locales/sk.json
vendor/assets/iD/iD/locales/sl.json
vendor/assets/iD/iD/locales/sq.json
vendor/assets/iD/iD/locales/sr.json
vendor/assets/iD/iD/locales/sv.json
vendor/assets/iD/iD/locales/ta.json
vendor/assets/iD/iD/locales/te.json
vendor/assets/iD/iD/locales/tl.json
vendor/assets/iD/iD/locales/tr.json
vendor/assets/iD/iD/locales/uk.json
vendor/assets/iD/iD/locales/vi.json
vendor/assets/iD/iD/locales/yue.json
vendor/assets/iD/iD/locales/zh-CN.json
vendor/assets/iD/iD/locales/zh-HK.json
vendor/assets/iD/iD/locales/zh-TW.json
vendor/assets/iD/iD/locales/zh.json
vendor/assets/iD/imagery.js
vendor/assets/iD/presets.js
vendor/assets/leaflet/images/layers-2x.png
vendor/assets/leaflet/images/layers.png
vendor/assets/leaflet/images/marker-icon-2x.png
vendor/assets/leaflet/images/marker-icon.png
vendor/assets/leaflet/images/marker-shadow.png
vendor/assets/leaflet/leaflet.css
vendor/assets/leaflet/leaflet.js
vendor/assets/leaflet/leaflet.locate.js
vendor/assets/leaflet/leaflet.locationfilter.js
vendor/assets/leaflet/leaflet.osm.js
vendor/assets/leaflet/leaflet.polyline.js

index f12f24a9f4c0b4a6215032efadfed4a27845042d..975457d9572a6670386e154be340781a44913299 100644 (file)
@@ -1,5 +1,9 @@
 inherit_from: .rubocop_todo.yml
 
+AllCops:
+  Include:
+    - '**/*.builder'
+
 Rails:
   Enabled: true
 
@@ -33,3 +37,6 @@ Style/HashSyntax:
 
 Style/StringLiterals:
   EnforcedStyle: double_quotes
+
+Rails/HttpPositionalArguments:
+  Enabled: false
index 191e82b39b4389e0a115941fdc52a6a2de7ec639..95ddea8f893b186fa297cfddcc3a176a0aed2f71 100644 (file)
@@ -1,6 +1,6 @@
 # This configuration was generated by
 # `rubocop --auto-gen-config`
-# on 2015-08-18 20:27:49 +0100 using RuboCop version 0.33.0.
+# on 2016-10-20 21:45:27 +0100 using RuboCop version 0.44.1.
 # The point is for the user to remove these configuration records
 # one by one as the offenses are removed from the code base.
 # Note that changes in the inspected code, or installation of new
@@ -14,11 +14,11 @@ Lint/AmbiguousOperator:
     - 'test/lib/bounding_box_test.rb'
     - 'test/lib/country_test.rb'
 
-# Offense count: 115
+# Offense count: 117
 Lint/AmbiguousRegexpLiteral:
   Enabled: false
 
-# Offense count: 29
+# Offense count: 30
 # Configuration parameters: AllowSafeAssignment.
 Lint/AssignmentInCondition:
   Exclude:
@@ -36,11 +36,6 @@ Lint/AssignmentInCondition:
     - 'lib/osm.rb'
     - 'script/deliver-message'
 
-# Offense count: 3
-Lint/FormatParameterMismatch:
-  Exclude:
-    - 'app/controllers/swf_controller.rb'
-
 # Offense count: 5
 Lint/HandleExceptions:
   Exclude:
@@ -48,16 +43,19 @@ Lint/HandleExceptions:
     - 'app/controllers/user_controller.rb'
     - 'config/initializers/session.rb'
 
-# Offense count: 8
-Lint/ParenthesesAsGroupedExpression:
+# Offense count: 2
+Lint/ShadowingOuterLocalVariable:
   Exclude:
-    - 'test/controllers/amf_controller_test.rb'
-    - 'test/lib/bounding_box_test.rb'
-    - 'test/models/user_preference_test.rb'
+    - 'app/views/changeset/list.atom.builder'
 
-# Offense count: 671
+# Offense count: 630
 Metrics/AbcSize:
-  Max: 277
+  Max: 271
+
+# Offense count: 35
+# Configuration parameters: CountComments.
+Metrics/BlockLength:
+  Max: 295
 
 # Offense count: 12
 Metrics/BlockNesting:
@@ -66,18 +64,19 @@ Metrics/BlockNesting:
 # Offense count: 62
 # Configuration parameters: CountComments.
 Metrics/ClassLength:
-  Max: 1654
+  Max: 1652
 
-# Offense count: 67
+# Offense count: 69
 Metrics/CyclomaticComplexity:
   Max: 20
 
-# Offense count: 2535
-# Configuration parameters: AllowURI, URISchemes.
+# Offense count: 2826
+# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives.
+# URISchemes: http, https
 Metrics/LineLength:
   Max: 962
 
-# Offense count: 628
+# Offense count: 612
 # Configuration parameters: CountComments.
 Metrics/MethodLength:
   Max: 179
@@ -85,26 +84,61 @@ Metrics/MethodLength:
 # Offense count: 1
 # Configuration parameters: CountComments.
 Metrics/ModuleLength:
-  Max: 131
+  Max: 147
 
 # Offense count: 4
 # Configuration parameters: CountKeywordArgs.
 Metrics/ParameterLists:
   Max: 9
 
-# Offense count: 69
+# Offense count: 71
 Metrics/PerceivedComplexity:
   Max: 23
 
 # Offense count: 2
 # Configuration parameters: Include.
+# Include: app/**/*.rb, config/**/*.rb, lib/**/*.rb
+Rails/Exit:
+  Exclude:
+    - 'lib/**/*.rake'
+    - 'lib/daemons/gpx_import.rb'
+
+# Offense count: 2
+# Configuration parameters: Include.
+# Include: app/models/**/*.rb
 Rails/HasAndBelongsToMany:
   Exclude:
     - 'app/models/changeset.rb'
     - 'app/models/user.rb'
 
-# Offense count: 66
+# Offense count: 5
+# Configuration parameters: Include.
+# Include: db/migrate/*.rb
+Rails/NotNullColumn:
+  Exclude:
+    - 'db/migrate/002_cleanup_osm_db.rb'
+    - 'db/migrate/020_populate_node_tags_and_remove.rb'
+    - 'db/migrate/021_move_to_innodb.rb'
+    - 'db/migrate/025_add_end_time_to_changesets.rb'
+    - 'db/migrate/20120404205604_add_user_and_description_to_redaction.rb'
+
+# Offense count: 17
+Rails/OutputSafety:
+  Exclude:
+    - 'app/controllers/user_controller.rb'
+    - 'app/helpers/application_helper.rb'
+    - 'app/helpers/changeset_helper.rb'
+    - 'app/helpers/geocoder_helper.rb'
+    - 'app/helpers/note_helper.rb'
+    - 'app/helpers/open_graph_helper.rb'
+    - 'app/helpers/user_blocks_helper.rb'
+    - 'app/helpers/user_roles_helper.rb'
+    - 'lib/rich_text.rb'
+    - 'test/helpers/application_helper_test.rb'
+
+# Offense count: 74
 # Configuration parameters: EnforcedStyle, SupportedStyles.
+# SupportedStyles: strict, flexible
 Rails/TimeZone:
   Enabled: false
 
@@ -122,27 +156,16 @@ Style/AsciiComments:
   Exclude:
     - 'test/models/message_test.rb'
 
-# Offense count: 310
+# Offense count: 220
 Style/Documentation:
   Enabled: false
 
-# Offense count: 38
-# Configuration parameters: MinBodyLength.
-Style/GuardClause:
+# Offense count: 1
+# Cop supports --auto-correct.
+# Configuration parameters: MaxLineLength.
+Style/IfUnlessModifier:
   Exclude:
-    - 'app/controllers/application_controller.rb'
-    - 'app/controllers/diary_entry_controller.rb'
-    - 'app/controllers/message_controller.rb'
-    - 'app/controllers/notes_controller.rb'
-    - 'app/controllers/site_controller.rb'
-    - 'app/controllers/user_blocks_controller.rb'
-    - 'app/controllers/user_controller.rb'
-    - 'app/controllers/user_roles_controller.rb'
-    - 'app/helpers/application_helper.rb'
-    - 'app/models/changeset.rb'
-    - 'app/models/user.rb'
-    - 'lib/diff_reader.rb'
-    - 'lib/object_metadata.rb'
+    - 'app/controllers/way_controller.rb'
 
 # Offense count: 60
 # Cop supports --auto-correct.
@@ -159,27 +182,19 @@ Style/LineEndConcatenation:
     - 'test/controllers/relation_controller_test.rb'
     - 'test/controllers/way_controller_test.rb'
 
-# Offense count: 69
+# Offense count: 71
 # Cop supports --auto-correct.
 Style/NumericLiterals:
   MinDigits: 11
 
-# Offense count: 42
-# Cop supports --auto-correct.
-Style/PerlBackrefs:
-  Exclude:
-    - 'app/controllers/amf_controller.rb'
-    - 'app/controllers/application_controller.rb'
-    - 'app/helpers/browse_helper.rb'
-    - 'config/initializers/paperclip.rb'
-    - 'lib/id.rb'
-    - 'lib/potlatch.rb'
-    - 'test/lib/i18n_test.rb'
-
 # Offense count: 8
-# Configuration parameters: NamePrefix, NamePrefixBlacklist.
+# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist.
+# NamePrefix: is_, has_, have_
+# NamePrefixBlacklist: is_, has_, have_
+# NameWhitelist: is_a?
 Style/PredicateName:
   Exclude:
+    - 'spec/**/*'
     - 'app/models/changeset.rb'
     - 'app/models/old_node.rb'
     - 'app/models/old_relation.rb'
@@ -188,17 +203,14 @@ Style/PredicateName:
     - 'lib/classic_pagination/pagination.rb'
 
 # Offense count: 97
+# Cop supports --auto-correct.
 # Configuration parameters: EnforcedStyle, SupportedStyles.
+# SupportedStyles: compact, exploded
 Style/RaiseArgs:
   Enabled: false
 
 # Offense count: 2
+# Cop supports --auto-correct.
 Style/RescueModifier:
   Exclude:
     - 'app/helpers/browse_helper.rb'
-
-# Offense count: 8
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
-Style/StringLiteralsInInterpolation:
-  Enabled: false
index 6c41bc8b82521802dc6ec577ea93e38b2ceff9f0..ad8f7e599ea42dff4504becf9e0aaa15625a942d 100644 (file)
@@ -1,7 +1,7 @@
 sudo: false
 language: ruby
 rvm:
-  - 2.1.8
+  - 2.3.1
 cache: bundler
 addons:
   postgresql: 9.1
@@ -26,4 +26,4 @@ before_script:
 script:
   - bundle exec rubocop -f fuubar
   - bundle exec rake jshint
-  - bundle exec rake test
+  - bundle exec rake test:db
diff --git a/Gemfile b/Gemfile
index dfd87eb849ff2490b495e62669fa3cf8e7e8cb0c..2cbb1cbef67ed982bf00398e47c3557d778c3643 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -1,7 +1,7 @@
 source "https://rubygems.org"
 
 # Require rails
-gem "rails", "4.2.6"
+gem "rails", "4.2.7.1"
 
 # Require things which have moved to gems in ruby 1.9
 gem "bigdecimal", "~> 1.1.0", :platforms => :ruby_19
@@ -63,6 +63,7 @@ gem "omniauth-openid"
 gem "omniauth-google-oauth2", ">= 0.2.7"
 gem "omniauth-facebook"
 gem "omniauth-windowslive"
+gem "omniauth-github"
 
 # Markdown formatting support
 gem "redcarpet"
@@ -80,9 +81,8 @@ gem "SystemTimer", ">= 1.1.3", :require => "system_timer", :platforms => :ruby_1
 # Load faraday for mockable HTTP client
 gem "faraday"
 
-# Load httpclient and soap4r for SOAP support for Quova GeoIP queries
-gem "httpclient"
-gem "soap4r-ruby1.9"
+# Load geoip for querying Maxmind GeoIP database
+gem "geoip"
 
 # Load memcache client in case we are using it
 gem "dalli"
@@ -108,5 +108,6 @@ group :development, :test do
   gem "jshint"
   gem "konacha"
   gem "poltergeist"
+  gem "factory_girl_rails"
   gem "coveralls", :require => false
 end
index 29f98975307792652f3e2ad590e72f86c224ccbd..d03cd5ad2504d67a9f8dc7a918cc7bdec9febce3 100644 (file)
@@ -2,38 +2,38 @@ GEM
   remote: https://rubygems.org/
   specs:
     SystemTimer (1.2.3)
-    actionmailer (4.2.6)
-      actionpack (= 4.2.6)
-      actionview (= 4.2.6)
-      activejob (= 4.2.6)
+    actionmailer (4.2.7.1)
+      actionpack (= 4.2.7.1)
+      actionview (= 4.2.7.1)
+      activejob (= 4.2.7.1)
       mail (~> 2.5, >= 2.5.4)
       rails-dom-testing (~> 1.0, >= 1.0.5)
-    actionpack (4.2.6)
-      actionview (= 4.2.6)
-      activesupport (= 4.2.6)
+    actionpack (4.2.7.1)
+      actionview (= 4.2.7.1)
+      activesupport (= 4.2.7.1)
       rack (~> 1.6)
       rack-test (~> 0.6.2)
       rails-dom-testing (~> 1.0, >= 1.0.5)
       rails-html-sanitizer (~> 1.0, >= 1.0.2)
     actionpack-page_caching (1.0.2)
       actionpack (>= 4.0.0, < 5)
-    actionview (4.2.6)
-      activesupport (= 4.2.6)
+    actionview (4.2.7.1)
+      activesupport (= 4.2.7.1)
       builder (~> 3.1)
       erubis (~> 2.7.0)
       rails-dom-testing (~> 1.0, >= 1.0.5)
       rails-html-sanitizer (~> 1.0, >= 1.0.2)
-    activejob (4.2.6)
-      activesupport (= 4.2.6)
+    activejob (4.2.7.1)
+      activesupport (= 4.2.7.1)
       globalid (>= 0.3.0)
-    activemodel (4.2.6)
-      activesupport (= 4.2.6)
+    activemodel (4.2.7.1)
+      activesupport (= 4.2.7.1)
       builder (~> 3.1)
-    activerecord (4.2.6)
-      activemodel (= 4.2.6)
-      activesupport (= 4.2.6)
+    activerecord (4.2.7.1)
+      activemodel (= 4.2.7.1)
+      activesupport (= 4.2.7.1)
       arel (~> 6.0)
-    activesupport (4.2.6)
+    activesupport (4.2.7.1)
       i18n (~> 0.7)
       json (~> 1.7, >= 1.7.7)
       minitest (~> 5.1)
@@ -41,12 +41,12 @@ GEM
       tzinfo (~> 1.1)
     addressable (2.4.0)
     arel (6.0.3)
-    ast (2.2.0)
-    autoprefixer-rails (6.3.5)
+    ast (2.3.0)
+    autoprefixer-rails (6.5.1)
       execjs
     bigdecimal (1.1.0)
     builder (3.2.2)
-    capybara (2.6.2)
+    capybara (2.10.1)
       addressable
       mime-types (>= 1.16)
       nokogiri (>= 1.3.3)
@@ -65,45 +65,50 @@ GEM
       coffee-script-source
       execjs
     coffee-script-source (1.10.0)
-    colorize (0.7.7)
-    composite_primary_keys (8.1.2)
+    colorize (0.8.1)
+    composite_primary_keys (8.1.4)
       activerecord (~> 4.2.0)
-    concurrent-ruby (1.0.1)
-    coveralls (0.8.13)
-      json (~> 1.8)
-      simplecov (~> 0.11.0)
+    concurrent-ruby (1.0.2)
+    coveralls (0.8.15)
+      json (>= 1.8, < 3)
+      simplecov (~> 0.12.0)
       term-ansicolor (~> 1.3)
       thor (~> 0.19.1)
-      tins (~> 1.6.0)
+      tins (>= 1.6.0, < 2)
     crass (1.0.2)
     dalli (2.7.6)
     deadlock_retry (1.2.0)
     docile (1.1.5)
     dynamic_form (1.1.4)
     erubis (2.7.0)
-    execjs (2.6.0)
-    exifr (1.2.4)
+    execjs (2.7.0)
+    exifr (1.2.5)
+    factory_girl (4.7.0)
+      activesupport (>= 3.0.0)
+    factory_girl_rails (4.7.0)
+      factory_girl (~> 4.7.0)
+      railties (>= 3.0.0)
     faraday (0.9.2)
       multipart-post (>= 1.2, < 3)
-    fspath (2.1.1)
-    globalid (0.3.6)
+    fspath (3.0.1)
+    geoip (1.6.2)
+    globalid (0.3.7)
       activesupport (>= 4.1.0)
-    hashie (3.4.3)
+    hashie (3.4.6)
     htmlentities (4.3.4)
     http_accept_language (2.0.5)
-    httpclient (2.7.1)
     i18n (0.7.0)
-    i18n-js (3.0.0.rc12)
+    i18n-js (3.0.0.rc14)
       i18n (~> 0.6, >= 0.6.6)
-    image_optim (0.22.1)
+    image_optim (0.24.0)
       exifr (~> 1.2, >= 1.2.2)
-      fspath (~> 2.1)
+      fspath (~> 3.0)
       image_size (~> 1.3)
       in_threads (~> 1.3)
       progress (~> 3.0, >= 3.0.1)
     image_size (1.4.2)
     in_threads (1.3.1)
-    jquery-rails (4.1.1)
+    jquery-rails (4.2.1)
       rails-dom-testing (>= 1, < 3)
       railties (>= 4.2.0)
       thor (>= 0.14, < 2.0)
@@ -117,7 +122,7 @@ GEM
     jsonify-rails (0.3.2)
       actionpack
       jsonify (< 0.4.0)
-    jwt (1.5.4)
+    jwt (1.5.6)
     kgio (2.10.0)
     konacha (4.0.0)
       actionpack (>= 4.1, < 5)
@@ -127,30 +132,30 @@ GEM
       sprockets (>= 2, < 4)
       sprockets-rails (>= 2, < 4)
       tilt
-    libv8 (3.16.14.13)
-    libxml-ruby (2.8.0)
+    libv8 (3.16.14.15)
+    libxml-ruby (2.9.0)
     logstash-event (1.2.02)
-    logstasher (0.9.0)
-      activerecord (>= 3.0)
-      activesupport (>= 3.0)
+    logstasher (1.0.1)
+      activerecord (>= 4.0)
+      activesupport (>= 4.0)
       logstash-event (~> 1.2.0)
       request_store
     loofah (2.0.3)
       nokogiri (>= 1.5.9)
     mail (2.6.4)
       mime-types (>= 1.16, < 4)
-    mime-types (3.0)
+    mime-types (3.1)
       mime-types-data (~> 3.2015)
-    mime-types-data (3.2016.0221)
+    mime-types-data (3.2016.0521)
     mimemagic (0.3.0)
-    mini_portile2 (2.0.0)
-    minitest (5.8.4)
-    multi_json (1.11.2)
+    mini_portile2 (2.1.0)
+    minitest (5.9.1)
+    multi_json (1.12.1)
     multi_xml (0.5.5)
     multipart-post (2.0.0)
-    nokogiri (1.6.7.2)
-      mini_portile2 (~> 2.0.0.rc2)
-    nokogumbo (1.4.7)
+    nokogiri (1.6.8.1)
+      mini_portile2 (~> 2.1.0)
+    nokogumbo (1.4.9)
       nokogiri
     oauth (0.4.7)
     oauth-plugin (0.5.1)
@@ -158,17 +163,20 @@ GEM
       oauth (~> 0.4.4)
       oauth2 (>= 0.5.0)
       rack
-    oauth2 (1.0.0)
+    oauth2 (1.2.0)
       faraday (>= 0.8, < 0.10)
       jwt (~> 1.0)
       multi_json (~> 1.3)
       multi_xml (~> 0.5)
-      rack (~> 1.2)
+      rack (>= 1.2, < 3)
     omniauth (1.3.1)
       hashie (>= 1.2, < 4)
       rack (>= 1.0, < 3)
-    omniauth-facebook (3.0.0)
+    omniauth-facebook (4.0.0)
       omniauth-oauth2 (~> 1.2)
+    omniauth-github (1.1.2)
+      omniauth (~> 1.0)
+      omniauth-oauth2 (~> 1.1)
     omniauth-google-oauth2 (0.4.1)
       jwt (~> 1.5.2)
       multi_json (~> 1.3)
@@ -180,26 +188,25 @@ GEM
     omniauth-openid (1.0.1)
       omniauth (~> 1.0)
       rack-openid (~> 1.3.1)
-    omniauth-windowslive (0.0.9.1)
+    omniauth-windowslive (0.0.11)
       multi_json (>= 1.0.3)
-      omniauth-oauth2 (~> 1.0)
-    paperclip (4.3.6)
+      omniauth-oauth2 (~> 1.4)
+    paperclip (4.3.7)
       activemodel (>= 3.2.0)
       activesupport (>= 3.2.0)
       cocaine (~> 0.5.5)
       mime-types
       mimemagic (= 0.3.0)
-    parser (2.3.0.7)
+    parser (2.3.1.4)
       ast (~> 2.2)
-    pg (0.18.4)
-    poltergeist (1.9.0)
+    pg (0.19.0)
+    poltergeist (1.11.0)
       capybara (~> 2.1)
       cliver (~> 0.3.1)
-      multi_json (~> 1.0)
       websocket-driver (>= 0.2.0)
     powerpack (0.1.1)
-    progress (3.1.1)
-    psych (2.0.17)
+    progress (3.2.2)
+    psych (2.1.1)
     r2 (0.2.6)
     rack (1.6.4)
     rack-cors (0.4.0)
@@ -209,16 +216,16 @@ GEM
     rack-test (0.6.3)
       rack (>= 1.0)
     rack-uri_sanitizer (0.0.2)
-    rails (4.2.6)
-      actionmailer (= 4.2.6)
-      actionpack (= 4.2.6)
-      actionview (= 4.2.6)
-      activejob (= 4.2.6)
-      activemodel (= 4.2.6)
-      activerecord (= 4.2.6)
-      activesupport (= 4.2.6)
+    rails (4.2.7.1)
+      actionmailer (= 4.2.7.1)
+      actionpack (= 4.2.7.1)
+      actionview (= 4.2.7.1)
+      activejob (= 4.2.7.1)
+      activemodel (= 4.2.7.1)
+      activerecord (= 4.2.7.1)
+      activesupport (= 4.2.7.1)
       bundler (>= 1.3.0, < 2.0)
-      railties (= 4.2.6)
+      railties (= 4.2.7.1)
       sprockets-rails
     rails-deprecated_sanitizer (1.0.3)
       activesupport (>= 4.2.0.alpha)
@@ -228,71 +235,70 @@ GEM
       rails-deprecated_sanitizer (>= 1.0.1)
     rails-html-sanitizer (1.0.3)
       loofah (~> 2.0)
-    rails-i18n (4.0.8)
+    rails-i18n (4.0.9)
       i18n (~> 0.7)
       railties (~> 4.0)
-    railties (4.2.6)
-      actionpack (= 4.2.6)
-      activesupport (= 4.2.6)
+    railties (4.2.7.1)
+      actionpack (= 4.2.7.1)
+      activesupport (= 4.2.7.1)
       rake (>= 0.8.7)
       thor (>= 0.18.1, < 2.0)
     rainbow (2.1.0)
-    rake (11.1.2)
+    rake (11.3.0)
     redcarpet (3.3.4)
     ref (2.0.0)
-    request_store (1.3.0)
-    rinku (1.7.3)
-    rubocop (0.39.0)
-      parser (>= 2.3.0.7, < 3.0)
+    request_store (1.3.1)
+    rinku (2.0.2)
+    rubocop (0.44.1)
+      parser (>= 2.3.1.1, < 3.0)
       powerpack (~> 0.1)
       rainbow (>= 1.99.1, < 3.0)
       ruby-progressbar (~> 1.7)
       unicode-display_width (~> 1.0, >= 1.0.1)
     ruby-openid (2.7.0)
-    ruby-progressbar (1.7.5)
-    sanitize (4.0.1)
+    ruby-progressbar (1.8.1)
+    sanitize (4.4.0)
       crass (~> 1.0.2)
       nokogiri (>= 1.4.4)
       nokogumbo (~> 1.4.1)
-    sass (3.4.21)
-    sass-rails (5.0.4)
-      railties (>= 4.0.0, < 5.0)
+    sass (3.4.22)
+    sass-rails (5.0.6)
+      railties (>= 4.0.0, < 6)
       sass (~> 3.1)
       sprockets (>= 2.8, < 4.0)
       sprockets-rails (>= 2.0, < 4.0)
       tilt (>= 1.1, < 3)
-    simplecov (0.11.2)
+    simplecov (0.12.0)
       docile (~> 1.1.0)
-      json (~> 1.8)
+      json (>= 1.8, < 3)
       simplecov-html (~> 0.10.0)
     simplecov-html (0.10.0)
-    soap4r-ruby1.9 (2.0.5)
-    sprockets (3.5.2)
+    sprockets (3.7.0)
       concurrent-ruby (~> 1.0)
       rack (> 1, < 3)
-    sprockets-rails (3.0.4)
+    sprockets-rails (3.2.0)
       actionpack (>= 4.0)
       activesupport (>= 4.0)
       sprockets (>= 3.0.0)
-    term-ansicolor (1.3.2)
+    term-ansicolor (1.4.0)
       tins (~> 1.0)
     therubyracer (0.12.2)
       libv8 (~> 3.16.14.0)
       ref
     thor (0.19.1)
     thread_safe (0.3.5)
-    tilt (2.0.2)
-    timecop (0.8.0)
-    tins (1.6.0)
+    tilt (2.0.5)
+    timecop (0.8.1)
+    tins (1.12.0)
     tzinfo (1.2.2)
       thread_safe (~> 0.1)
-    uglifier (3.0.0)
+    uglifier (3.0.2)
       execjs (>= 0.3.0, < 3)
-    unicode-display_width (1.0.2)
+    unicode-display_width (1.1.1)
     validates_email_format_of (1.6.3)
       i18n
     vendorer (0.1.16)
-    websocket-driver (0.6.3)
+    websocket-driver (0.6.4)
       websocket-extensions (>= 0.1.0)
     websocket-extensions (0.1.2)
     xpath (2.0.0)
@@ -312,10 +318,11 @@ DEPENDENCIES
   dalli
   deadlock_retry (>= 1.2.0)
   dynamic_form
+  factory_girl_rails
   faraday
+  geoip
   htmlentities
   http_accept_language (~> 2.0.0)
-  httpclient
   i18n-js (>= 3.0.0.rc10)
   image_optim (>= 0.22.0)
   jquery-rails
@@ -330,6 +337,7 @@ DEPENDENCIES
   oauth-plugin (>= 0.5.1)
   omniauth
   omniauth-facebook
+  omniauth-github
   omniauth-google-oauth2 (>= 0.2.7)
   omniauth-openid
   omniauth-windowslive
@@ -340,15 +348,17 @@ DEPENDENCIES
   r2
   rack-cors
   rack-uri_sanitizer
-  rails (= 4.2.6)
+  rails (= 4.2.7.1)
   rails-i18n (~> 4.0.0)
   redcarpet
   rinku (>= 1.2.2)
   rubocop
   sanitize
   sass-rails (~> 5.0)
-  soap4r-ruby1.9
   timecop
   uglifier (>= 1.3.0)
   validates_email_format_of (>= 1.5.1)
   vendorer
+
+BUNDLED WITH
+   1.10.6
index 055702a4c1cb6820e5f2528fc1d965512e86cce7..53a78384615b571e665291c01fb63bae962fda1d 100644 (file)
@@ -81,9 +81,9 @@ and adding:
 Installing other dependencies:
 
 * Install Homebrew from http://mxcl.github.io/homebrew/
-* Install the latest version of Ruby: brew install ruby
-* Install ImageMagick: brew install imagemagick
-* Install Bundler: gem install bundler
+* Install the latest version of Ruby: `brew install ruby`
+* Install ImageMagick: `brew install imagemagick`
+* Install Bundler: `gem install bundler`
 
 Note that OS X does not have a /home directory by default, so if you are using the GPX functions, you will need to change the directories specified in config/application.yml.
 
index d53bae1577d56071ad0ce0250dea7153fc871476..5b909454f0f4b538f118d0b0d335cbdc6ac12fa5 100644 (file)
--- a/README.md
+++ b/README.md
@@ -38,6 +38,5 @@ We're always keen to have more developers! Pull requests are very welcome.
 * Translation is managed by [Translatewiki](https://translatewiki.net/wiki/Translating:OpenStreetMap)
 * There is a [rails-dev@openstreetmap.org](http://lists.openstreetmap.org/listinfo/rails-dev) mailing list for development discussion.
 * IRC - there is the #osm-dev channel on irc.oftc.net.
-* There are also weekly meetings of the OpenStreetMap Foundation Engineering Working Group (EWG) on Mondays at 1700 UTC on the #osm-ewg channel.
 
 More details on contributing to the code are in the [CONTRIBUTING.md](CONTRIBUTING.md) file.
index 30ccee4415add9f9f51dab32f119aa70f8f9ebb5..9a951d586854d648471720058b90293c50a35f6c 100644 (file)
@@ -11,13 +11,13 @@ folder 'vendor/assets' do
   end
 
   folder 'leaflet' do
-    file 'leaflet.js', 'http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet-src.js'
-    file 'leaflet.css', 'http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css'
+    file 'leaflet.js', 'https://unpkg.com/leaflet@1.0.1/dist/leaflet-src.js'
+    file 'leaflet.css', 'https://unpkg.com/leaflet@1.0.1/dist/leaflet.css'
 
     [ 'layers.png', 'layers-2x.png',
       'marker-icon.png', 'marker-icon-2x.png',
       'marker-shadow.png' ].each do |image|
-      file "images/#{image}", "http://cdn.leafletjs.com/leaflet/v0.7.7/images/#{image}"
+      file "images/#{image}", "https://unpkg.com/leaflet@1.0.1/dist/images/#{image}"
     end
 
     from 'git://github.com/kajic/leaflet-locationfilter.git' do
@@ -26,7 +26,7 @@ folder 'vendor/assets' do
       folder 'img', 'src/img'
     end
 
-    from 'git://github.com/domoritz/leaflet-locatecontrol.git' do
+    from 'git://github.com/domoritz/leaflet-locatecontrol.git', :tag => 'v0.54.0' do
       file 'leaflet.locate.js', 'src/L.Control.Locate.js'
     end
 
@@ -34,7 +34,7 @@ folder 'vendor/assets' do
       file 'leaflet.osm.js', 'leaflet-osm.js'
     end
 
-    from 'git://github.com/jieter/Leaflet.encoded.git' do
+    from 'git://github.com/jieter/Leaflet.encoded.git', :tag => '0.0.8' do
       file 'leaflet.polyline.js', 'Polyline.encoded.js'
     end
   end
diff --git a/app/assets/images/banners/.keep b/app/assets/images/banners/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/app/assets/images/banners/donate-2016.jpg b/app/assets/images/banners/donate-2016.jpg
new file mode 100644 (file)
index 0000000..7e2e6eb
Binary files /dev/null and b/app/assets/images/banners/donate-2016.jpg differ
diff --git a/app/assets/images/banners/sotmasia-2016.jpg b/app/assets/images/banners/sotmasia-2016.jpg
new file mode 100644 (file)
index 0000000..fa5f1f0
Binary files /dev/null and b/app/assets/images/banners/sotmasia-2016.jpg differ
diff --git a/app/assets/images/banners/sotmlatam-2016.jpg b/app/assets/images/banners/sotmlatam-2016.jpg
new file mode 100644 (file)
index 0000000..97efa75
Binary files /dev/null and b/app/assets/images/banners/sotmlatam-2016.jpg differ
diff --git a/app/assets/images/github.png b/app/assets/images/github.png
new file mode 100644 (file)
index 0000000..b797e24
Binary files /dev/null and b/app/assets/images/github.png differ
diff --git a/app/assets/images/key/cyclemap/bicycle_parking.png b/app/assets/images/key/cyclemap/bicycle_parking.png
new file mode 100644 (file)
index 0000000..c900a44
Binary files /dev/null and b/app/assets/images/key/cyclemap/bicycle_parking.png differ
diff --git a/app/assets/images/key/cyclemap/bicycle_shop.png b/app/assets/images/key/cyclemap/bicycle_shop.png
new file mode 100644 (file)
index 0000000..5ccf714
Binary files /dev/null and b/app/assets/images/key/cyclemap/bicycle_shop.png differ
diff --git a/app/assets/images/key/cyclemap/common.png b/app/assets/images/key/cyclemap/common.png
new file mode 100644 (file)
index 0000000..7c10815
Binary files /dev/null and b/app/assets/images/key/cyclemap/common.png differ
diff --git a/app/assets/images/key/cyclemap/cycleway.png b/app/assets/images/key/cyclemap/cycleway.png
new file mode 100644 (file)
index 0000000..13bed4a
Binary files /dev/null and b/app/assets/images/key/cyclemap/cycleway.png differ
diff --git a/app/assets/images/key/cyclemap/cycleway_local.png b/app/assets/images/key/cyclemap/cycleway_local.png
new file mode 100644 (file)
index 0000000..2a29331
Binary files /dev/null and b/app/assets/images/key/cyclemap/cycleway_local.png differ
diff --git a/app/assets/images/key/cyclemap/cycleway_local13.png b/app/assets/images/key/cyclemap/cycleway_local13.png
new file mode 100644 (file)
index 0000000..3f2c535
Binary files /dev/null and b/app/assets/images/key/cyclemap/cycleway_local13.png differ
diff --git a/app/assets/images/key/cyclemap/cycleway_national.png b/app/assets/images/key/cyclemap/cycleway_national.png
new file mode 100644 (file)
index 0000000..0f5455f
Binary files /dev/null and b/app/assets/images/key/cyclemap/cycleway_national.png differ
diff --git a/app/assets/images/key/cyclemap/cycleway_national13.png b/app/assets/images/key/cyclemap/cycleway_national13.png
new file mode 100644 (file)
index 0000000..252b07a
Binary files /dev/null and b/app/assets/images/key/cyclemap/cycleway_national13.png differ
diff --git a/app/assets/images/key/cyclemap/cycleway_regional.png b/app/assets/images/key/cyclemap/cycleway_regional.png
new file mode 100644 (file)
index 0000000..7e3306e
Binary files /dev/null and b/app/assets/images/key/cyclemap/cycleway_regional.png differ
diff --git a/app/assets/images/key/cyclemap/cycleway_regional13.png b/app/assets/images/key/cyclemap/cycleway_regional13.png
new file mode 100644 (file)
index 0000000..9b3409f
Binary files /dev/null and b/app/assets/images/key/cyclemap/cycleway_regional13.png differ
diff --git a/app/assets/images/key/cyclemap/footway.png b/app/assets/images/key/cyclemap/footway.png
new file mode 100644 (file)
index 0000000..c78756f
Binary files /dev/null and b/app/assets/images/key/cyclemap/footway.png differ
diff --git a/app/assets/images/key/cyclemap/forest.png b/app/assets/images/key/cyclemap/forest.png
new file mode 100644 (file)
index 0000000..a7ebe8e
Binary files /dev/null and b/app/assets/images/key/cyclemap/forest.png differ
diff --git a/app/assets/images/key/cyclemap/lake.png b/app/assets/images/key/cyclemap/lake.png
new file mode 100644 (file)
index 0000000..918d496
Binary files /dev/null and b/app/assets/images/key/cyclemap/lake.png differ
diff --git a/app/assets/images/key/cyclemap/motorway.png b/app/assets/images/key/cyclemap/motorway.png
new file mode 100644 (file)
index 0000000..296f176
Binary files /dev/null and b/app/assets/images/key/cyclemap/motorway.png differ
diff --git a/app/assets/images/key/cyclemap/motorway12.png b/app/assets/images/key/cyclemap/motorway12.png
new file mode 100644 (file)
index 0000000..749493a
Binary files /dev/null and b/app/assets/images/key/cyclemap/motorway12.png differ
diff --git a/app/assets/images/key/cyclemap/primary.png b/app/assets/images/key/cyclemap/primary.png
new file mode 100644 (file)
index 0000000..78ae0e4
Binary files /dev/null and b/app/assets/images/key/cyclemap/primary.png differ
diff --git a/app/assets/images/key/cyclemap/primary12.png b/app/assets/images/key/cyclemap/primary12.png
new file mode 100644 (file)
index 0000000..fed37d0
Binary files /dev/null and b/app/assets/images/key/cyclemap/primary12.png differ
diff --git a/app/assets/images/key/cyclemap/rail.png b/app/assets/images/key/cyclemap/rail.png
new file mode 100644 (file)
index 0000000..0abf0c1
Binary files /dev/null and b/app/assets/images/key/cyclemap/rail.png differ
diff --git a/app/assets/images/key/cyclemap/rail14.png b/app/assets/images/key/cyclemap/rail14.png
new file mode 100644 (file)
index 0000000..957f17c
Binary files /dev/null and b/app/assets/images/key/cyclemap/rail14.png differ
diff --git a/app/assets/images/key/cyclemap/secondary.png b/app/assets/images/key/cyclemap/secondary.png
new file mode 100644 (file)
index 0000000..7928b18
Binary files /dev/null and b/app/assets/images/key/cyclemap/secondary.png differ
diff --git a/app/assets/images/key/cyclemap/secondary12.png b/app/assets/images/key/cyclemap/secondary12.png
new file mode 100644 (file)
index 0000000..cde0085
Binary files /dev/null and b/app/assets/images/key/cyclemap/secondary12.png differ
diff --git a/app/assets/images/key/cyclemap/toilets.png b/app/assets/images/key/cyclemap/toilets.png
new file mode 100644 (file)
index 0000000..d1c7a00
Binary files /dev/null and b/app/assets/images/key/cyclemap/toilets.png differ
diff --git a/app/assets/images/key/cyclemap/track.png b/app/assets/images/key/cyclemap/track.png
new file mode 100644 (file)
index 0000000..f294edc
Binary files /dev/null and b/app/assets/images/key/cyclemap/track.png differ
diff --git a/app/assets/images/key/cyclemap/trunk.png b/app/assets/images/key/cyclemap/trunk.png
new file mode 100644 (file)
index 0000000..d312a65
Binary files /dev/null and b/app/assets/images/key/cyclemap/trunk.png differ
diff --git a/app/assets/images/key/cyclemap/trunk12.png b/app/assets/images/key/cyclemap/trunk12.png
new file mode 100644 (file)
index 0000000..51230a0
Binary files /dev/null and b/app/assets/images/key/cyclemap/trunk12.png differ
index 42ec7b4cdf94c3098160e40542d81ca645bc3b32..079f4dd7fe229513f8c48a85d9d79df8adc5823c 100644 (file)
Binary files a/app/assets/images/routing-sprite.png and b/app/assets/images/routing-sprite.png differ
diff --git a/app/assets/images/routing-sprite.svg b/app/assets/images/routing-sprite.svg
new file mode 100644 (file)
index 0000000..15aa57b
--- /dev/null
@@ -0,0 +1,573 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="520"
+   height="20"
+   viewBox="0 0 520.00001 20"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="routing-sprite.svg"
+   inkscape:export-filename="/home/patrick/Code/openstreetmap-website/app/assets/images/routing-sprite.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90">
+  <defs
+     id="defs4" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="5.6568542"
+     inkscape:cx="131.24519"
+     inkscape:cy="13.736603"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:showpageshadow="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1080"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     showguides="false"
+     inkscape:guide-bbox="true"
+     units="px">
+    <inkscape:grid
+       type="xygrid"
+       id="grid4224" />
+    <sodipodi:guide
+       position="20.000001,31"
+       orientation="1,0"
+       id="guide4226" />
+    <sodipodi:guide
+       position="40.000001,19"
+       orientation="1,0"
+       id="guide4245" />
+    <sodipodi:guide
+       position="60.000002,29"
+       orientation="1,0"
+       id="guide4299" />
+    <sodipodi:guide
+       position="80.000002,35"
+       orientation="1,0"
+       id="guide4388" />
+    <sodipodi:guide
+       position="71.000002,10"
+       orientation="-0.7193398,-0.69465837"
+       id="guide4432"
+       inkscape:label=""
+       inkscape:color="rgb(0,0,255)" />
+    <sodipodi:guide
+       position="100,15"
+       orientation="1,0"
+       id="guide4499" />
+    <sodipodi:guide
+       position="120,15"
+       orientation="1,0"
+       id="guide4578" />
+    <sodipodi:guide
+       position="140,16"
+       orientation="1,0"
+       id="guide4580" />
+    <sodipodi:guide
+       position="160,21"
+       orientation="1,0"
+       id="guide4582" />
+    <sodipodi:guide
+       position="180,15"
+       orientation="1,0"
+       id="guide4729" />
+    <sodipodi:guide
+       position="200.00001,15"
+       orientation="1,0"
+       id="guide4731" />
+    <sodipodi:guide
+       position="220.00001,11"
+       orientation="1,0"
+       id="guide4747" />
+    <sodipodi:guide
+       position="78.000002,12"
+       orientation="-0.70710678,0.70710678"
+       id="guide4212"
+       inkscape:label=""
+       inkscape:color="rgb(0,0,255)" />
+    <sodipodi:guide
+       position="240.00001,19"
+       orientation="1,0"
+       id="guide4264" />
+    <sodipodi:guide
+       position="260.00001,19"
+       orientation="1,0"
+       id="guide4266" />
+    <sodipodi:guide
+       position="280.00001,5"
+       orientation="1,0"
+       id="guide4280" />
+    <sodipodi:guide
+       position="300.00001,10"
+       orientation="1,0"
+       id="guide4297" />
+    <sodipodi:guide
+       position="320.00001,24"
+       orientation="1,0"
+       id="guide4305" />
+    <sodipodi:guide
+       position="340.00001,28"
+       orientation="1,0"
+       id="guide4335" />
+    <sodipodi:guide
+       position="360.00001,30"
+       orientation="1,0"
+       id="guide4337" />
+    <sodipodi:guide
+       position="380.00001,19"
+       orientation="1,0"
+       id="guide4376" />
+    <sodipodi:guide
+       position="400.00001,19"
+       orientation="1,0"
+       id="guide4382" />
+    <sodipodi:guide
+       position="420.00001,36"
+       orientation="1,0"
+       id="guide4394" />
+    <sodipodi:guide
+       position="440.00001,20"
+       orientation="1,0"
+       id="guide4449" />
+    <sodipodi:guide
+       position="460.00001,22"
+       orientation="1,0"
+       id="guide4451" />
+    <sodipodi:guide
+       position="480.00001,20"
+       orientation="1,0"
+       id="guide4485" />
+    <sodipodi:guide
+       position="500.00001,40"
+       orientation="1,0"
+       id="guide4487" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-1032.3622)">
+    <image
+       y="1002.3622"
+       x="1.7763568e-15"
+       id="image4217"
+       xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAWgAAAAUCAMAAACXrFfpAAABOFBMVEUAAAB/f39/f39/f39/f396 enoAAAB7e3t7e3t4eHh5eXl5eXl6enp3d3d4eHgAAAB3d3d1dXVzc3MAAABwcHBvb29ubm4AAABt bW1sbGxsbGxsbGxra2tra2toaGhoaGhqamoAAABmZmZoaGgAAABnZ2dkZGQAAABiYmJXV1dXV1cA AAAAAABMTEwAAAAAAABDQ0MAAAA1NTU1NTUxMTEAAAAxMTEAAAAAAAAmJiYlJSUkJCQjIyMiIiIA AAAcHBwAAAAAAAAAAAAAAAAUFBQAAAAAAAAQEBAPDw8AAAAPDw8AAAAAAAANDQ0MDAwAAAAAAAAM DAwKCgoAAAAAAAAICAgICAgAAAAHBwcAAAAHBwcGBgYAAAAAAAAAAAAAAAADAwMAAAAAAAAAAAAA AAAAAAAAAAAAAABULW3yAAAAZ3RSTlMAAQIGCw4QEBIUFhcZGh0gICItMDQ5PEBAQUJERUZHSEhK SkxMTU9QUFZXWGBgZGZpcHl6f4CAiJCRk5SXmaCmrLC1uLzAxMXIyMrM0NDT09TU29zg4OLk5ebm 6fDx8/T09vf4+/z9ttm2NwAABH9JREFUeF7tV+9zFTUUzQOMFZUAiwZbkB9bXYEU3UI0FVhcNQVx rQpbsBopFuX8//+BMy/vvd3k7mRnio8PHc/HOyc35545yWbZkYOQtKYSvDeOgg/Xs4JR8OI/kDnc Q6jX02wqqtZlKR7tN47MWtNfOMRZOZ/n+fmVuNwMD6hRhDmQSlcNXCCpJAKVtbYiRnIViAVspQsp w9Wo0+OmNXMHQWeoUjzabxwSsP1mNDMn1/KHAB7ma+9EK9uhfi1CPdxgijJMggtjnzWeZViSVnmW jqaF0yyBtGYNVNRTiEEe7Xc4oxXtxS78Co+fVoO6BSTpZgEgKt78GyCCHGxvFN5iBh12a6kD+OsK C2EBtCqR6pRm8SdI0QCwMQ8AsvF+FGLA6HkcpV64cOwz5B7Iw3B492gsXVgtp0XVXRFTPANQyX5S jSya/iyyBvDMs1WfCFeQrNGqrOFqyRjRTL0CGh7SDnAANcQb7Uf3FS01ugRQe+kL6uRT5Jfu/nb3 UmR04++DENmTOAu8jszXmKMbUMxa8WZxPHmDHnSQK8AQo1+uswDKExUb0VyUN4B1VQSBLixspnnI W/c82m9k3woqMtofTMjI6E9waxfA7i3kE5IiQcYLjc5aAO0VmCGj3fzclPOsyO48CO0GjGa1KxyA RgRG/wPU8UH3EGxM8w3gJovQ4BdvM+Wl+9F9BdDGRvvwtbxv9MnVTcyxufruwkBX/Qh8VTfkCq2t DZ4JQM1ZkwXfFCnlE7guMvUiFw5YULl2aKSUVd9oVTHRRPeTdp8DCEMJdNlPajYziXE6XMEor2Is 3Y/ua19iX4dGq9YAKJuqb/SFB+jwYG2RmNmHQPDoUeA4r8NLrAzf/3pqm0AtyDeFfF2EhfArupKc jdM3WjILOHKjzo5XUrMGtrcBE8Zl77s9H0rKS/aj+4pCY12FRgvGpgOIvtFn76HDvbPpL64F1HQ9 edPERpeK0ValySywrqquQ1lGRnuERnN/ZAeNrkdeCQ5qKrNnVjk91DUqwisATvsl9/VeclNIwApT BAPw5gd8Y33L41efYo6nV48nRJNSyujhdRYHwD6K0RUA0pUSM5RpgZk/CE2/rOGPuiUPZs8j/ZL7 +tAW2Aeew0ZyZe+ZdeY25rh9hi3XaOH8RXhYo+nDvB1JIPcZbUOjDWNMBcqF/7N1yGi/9L7eaP/9 cyKWa7tpJznmyCdLNdp7CscPazR90zfZiEDWoBa8ggtFl0y68DC0nteO9aP7ash5hjSRK3tfgouP XuHF9y/w6tFFtmyjufNqDmd0iELrgrFRYzBFwKww8BPT8Ui/9L7KZrMpHKdyy0WgT63lG1vX8+tb G/naqcmSjWYajr+e0RRpzdm3wM9RUe/hueGUt50cOA3uoFNyz23uPL6zcf+P+xt3Hu9snluC0ZEc zZZvdKxRUp5lKR7tNw7jeEpujp3Z1YHd35Ev22hmxFE1Wpik3MubH324sXXtg2tff7H68ZeX2dFD Zm1G0mdNgrcUrLw/YW+dPsFOnH6bHXtvhb0p/I9/AQmEF7Y+Eo3CAAAAAElFTkSuQmCC "
+       preserveAspectRatio="none"
+       height="20.000017"
+       width="360" />
+    <path
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 9,1039.3309 3.6e-5,10.0313 1.999964,0 -3.5e-5,-10.0313 z"
+       id="path4446"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       sodipodi:nodetypes="cccc"
+       inkscape:connector-curvature="0"
+       id="path4448"
+       d="m 15,1039.3466 -5,-4.9844 -5,5 z"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 87.125,4.984375 87.125,5 86,5 86,12.005859 82,12 l 5,5 5,-4.984375 -4,-0.0059 0,-5.025391 7,0 L 95,17 l 2,0 0,-12 -0.46875,0 0,-0.015625 -9.40625,0 z"
+       transform="translate(0,1032.3622)"
+       id="path4509"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 28,3.9882812 2.814453,2.8203126 -4.777344,4.7460942 0,0.04297 -0.03711,0 L 26,17 28,17 28,12.423828 32.228516,8.2226562 35,11 35,4 28,3.9882812 Z"
+       transform="translate(0,1032.3622)"
+       id="path4450"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 53,4 0.0059,3.984375 -6.005859,0 0,2 L 47,17 l 2,0 0,-7.015625 4.009766,0 L 53.015625,14 58,9 53,4 Z"
+       transform="translate(0,1032.3622)"
+       id="path4208"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 67.025391,4.4101562 67.003906,17 l 2,0 0,-7.5527344 3.685547,3.8710934 -2.683114,2.694508 6.989812,0.05505 0.01101,-7.0846724 -2.854816,2.9210504 z"
+       transform="translate(0,1032.3622)"
+       id="path4424"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccc" />
+    <path
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 170,1035.3622 -4,5 3,0 0,5 2,0 0,-5 3,0 z"
+       id="path4735"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccc" />
+    <g
+       id="g4237">
+      <path
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 189,1039.3309 4e-5,10.0313 1.99996,0 -3e-5,-10.0313 z"
+         id="path4233"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="ccccc" />
+      <path
+         sodipodi:nodetypes="cccc"
+         inkscape:connector-curvature="0"
+         id="path4235"
+         d="m 195,1039.3466 -5,-4.9844 -5,5 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    </g>
+    <path
+       id="path4221"
+       d="m 112.00001,1036.3505 -2.81445,2.8203 4.77734,4.7461 0,0.043 0.0371,0 0,5.4023 -2,0 0,-4.5762 -4.22852,-4.2011 -2.77148,2.7773 0,-7 7,-0.012 z"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       inkscape:connector-curvature="0" />
+    <path
+       id="path4223"
+       d="m 128.00028,1036.3622 -0.006,3.9844 6.00586,0 0,2 0,7.0156 -2,0 0,-7.0156 -4.00977,0 -0.006,4.0156 -4.98437,-5 5,-5 z"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       inkscape:connector-curvature="0" />
+    <path
+       sodipodi:nodetypes="cccccccccc"
+       inkscape:connector-curvature="0"
+       id="path4225"
+       d="m 153.98575,1036.7724 0.0215,12.5898 -2,0 0,-7.5527 -3.68555,3.8711 2.68312,2.6945 -6.98982,0.055 -0.011,-7.0847 2.85482,2.9211 z"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <g
+       id="g4254"
+       transform="translate(-2.0000461,0)">
+      <circle
+         r="3"
+         transform="scale(1,-1)"
+         cy="-1044.3622"
+         cx="210.04105"
+         id="path4231"
+         style="opacity:1;fill:none;fill-opacity:0.43824702;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <path
+         id="path4247"
+         transform="translate(0,1032.3622)"
+         d="m 211,3.9882812 2.81445,2.8203126 -1.76562,1.7539062 c 0.58436,0.3442274 1.07073,0.8277607 1.41797,1.4101562 l 1.76172,-1.75 L 218,11 218,4 211,3.9882812 Z M 209,15.84375 209,17 l 2,0 0,-1.130859 C 210.69097,15.946541 210.3729,16 210.04102,16 209.67912,16 209.3342,15.935262 209,15.84375 Z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       transform="translate(17.999954,0)"
+       id="g4258">
+      <circle
+         style="opacity:1;fill:none;fill-opacity:0.43824702;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="circle4260"
+         cx="210.04105"
+         cy="-1044.3622"
+         transform="scale(1,-1)"
+         r="3" />
+      <path
+         inkscape:connector-curvature="0"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 211,3.9882812 2.81445,2.8203126 -1.76562,1.7539062 c 0.58436,0.3442274 1.07073,0.8277607 1.41797,1.4101562 l 1.76172,-1.75 L 218,11 218,4 211,3.9882812 Z M 209,15.84375 209,17 l 2,0 0,-1.130859 C 210.69097,15.946541 210.3729,16 210.04102,16 209.67912,16 209.3342,15.935262 209,15.84375 Z"
+         transform="translate(0,1032.3622)"
+         id="path4262" />
+    </g>
+    <g
+       id="g4268"
+       transform="translate(37.999954,0)">
+      <circle
+         r="3"
+         transform="scale(1,-1)"
+         cy="-1044.3622"
+         cx="210.04105"
+         id="circle4270"
+         style="opacity:1;fill:none;fill-opacity:0.43824702;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <path
+         id="path4272"
+         transform="translate(0,1032.3622)"
+         d="m 211,3.9882812 2.81445,2.8203126 -1.76562,1.7539062 c 0.58436,0.3442274 1.07073,0.8277607 1.41797,1.4101562 l 1.76172,-1.75 L 218,11 218,4 211,3.9882812 Z M 209,15.84375 209,17 l 2,0 0,-1.130859 C 210.69097,15.946541 210.3729,16 210.04102,16 209.67912,16 209.3342,15.935262 209,15.84375 Z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       id="g4274"
+       transform="translate(80,0)">
+      <path
+         sodipodi:nodetypes="ccccc"
+         inkscape:connector-curvature="0"
+         id="path4276"
+         d="m 189,1039.3309 4e-5,10.0313 1.99996,0 -3e-5,-10.0313 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+      <path
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 195,1039.3466 -5,-4.9844 -5,5 z"
+         id="path4278"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccc" />
+    </g>
+    <path
+       id="path4295"
+       d="m 290,1035.3622 a 2,2 0 0 0 -2,2 2,2 0 0 0 2,2 2,2 0 0 0 2,-2 2,2 0 0 0 -2,-2 z m 0,4 -4,5 3,0 0,5 2,0 0,-5 3,0 -4,-5 z"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       inkscape:connector-curvature="0" />
+    <g
+       id="g4313">
+      <g
+         id="g4299"
+         transform="translate(115.01146,2)">
+        <path
+           sodipodi:nodetypes="ccccc"
+           inkscape:connector-curvature="0"
+           id="path4301"
+           d="m 189,1037.3422 4e-5,7.9763 1.99996,0 -3e-5,-7.9763 z"
+           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+        <path
+           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="M 192.99451,1037.3474 190,1034.3622 l -3.01146,3.0115 z"
+           id="path4303"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="cccc" />
+      </g>
+      <g
+         transform="matrix(1,0,0,-1,123.01146,2083.7244)"
+         id="g4307">
+        <path
+           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="m 189,1039.3309 4e-5,10.0313 1.99996,0 -3e-5,-10.0313 z"
+           id="path4309"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="ccccc" />
+        <path
+           sodipodi:nodetypes="cccc"
+           inkscape:connector-curvature="0"
+           id="path4311"
+           d="m 195,1039.3466 -5,-4.9844 -5,5 z"
+           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+      </g>
+    </g>
+    <g
+       id="g4321"
+       transform="matrix(-1,0,0,-1,640.01146,2083.7244)">
+      <g
+         transform="translate(115.01146,2)"
+         id="g4323">
+        <path
+           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="m 189,1037.3422 4e-5,7.9763 1.99996,0 -3e-5,-7.9763 z"
+           id="path4325"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="ccccc" />
+        <path
+           sodipodi:nodetypes="cccc"
+           inkscape:connector-curvature="0"
+           id="path4327"
+           d="M 192.99451,1037.3474 190,1034.3622 l -3.01146,3.0115 z"
+           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+      </g>
+      <g
+         id="g4329"
+         transform="matrix(1,0,0,-1,123.01146,2083.7244)">
+        <path
+           sodipodi:nodetypes="ccccc"
+           inkscape:connector-curvature="0"
+           id="path4331"
+           d="m 189,1039.3309 4e-5,10.0313 1.99996,0 -3e-5,-10.0313 z"
+           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+        <path
+           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="m 195,1039.3466 -5,-4.9844 -5,5 z"
+           id="path4333"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="cccc" />
+      </g>
+    </g>
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 349,3 0,1 -3,0 0,5.2265625 L 343.95508,10 347,13 l 0,0.904297 1.61133,1.425781 1.88867,-1.671875 1.89062,1.671875 L 354,13.90625 354,13 357.04492,10.044922 355,9.2617188 355,4 l -3,0 0,-1 -3,0 z m -2,2 7,0 0,3.8769531 L 350.48633,7.53125 347,8.8496094 347,5 Z m -0.2793,9.992188 -2.2207,1.966796 0.66211,0.748047 1.55859,-1.378906 L 348.61133,18 350.5,16.328125 352.39062,18 l 1.88868,-1.671875 1.55859,1.378906 0.66211,-0.748047 -2.2207,-1.966796 -1.88868,1.673828 -1.89062,-1.673828 -1.88867,1.673828 -1.89063,-1.673828 z"
+       transform="translate(0,1032.3622)"
+       id="path4341"
+       inkscape:connector-curvature="0" />
+    <g
+       id="g4384">
+      <path
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 370,1036.3505 2.81445,2.8203 -4.77734,4.7461 0,0.043 -0.0371,0 0,5.4023 2,0 0,-4.5762 4.22852,-4.2011 2.77148,2.7773 0,-7 -7,-0.012 z"
+         id="path4374"
+         inkscape:connector-curvature="0" />
+      <path
+         sodipodi:nodetypes="ccccccccc"
+         inkscape:connector-curvature="0"
+         id="path4378"
+         d="m 365.18556,1039.1708 4.77734,4.7461 0,0.043 0.0371,0 0,5.4023 -2,0 0,-4.5762 -4.22852,-4.2011 z"
+         style="fill:#000000;fill-opacity:0.5098038;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    </g>
+    <g
+       id="g4388"
+       transform="matrix(-1,0,0,1,760.00001,0)">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4390"
+         d="m 370,1036.3505 2.81445,2.8203 -4.77734,4.7461 0,0.043 -0.0371,0 0,5.4023 2,0 0,-4.5762 4.22852,-4.2011 2.77148,2.7773 0,-7 -7,-0.012 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+      <path
+         style="fill:#000000;fill-opacity:0.5098038;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 365.18556,1039.1708 4.77734,4.7461 0,0.043 0.0371,0 0,5.4023 -2,0 0,-4.5762 -4.22852,-4.2011 z"
+         id="path4392"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="ccccccccc" />
+    </g>
+    <g
+       id="g4438">
+      <path
+         id="path4421"
+         transform="translate(0,1032.3622)"
+         d="m 407.0293,3.9882812 0,5.4023438 0.0371,0 0,0.042969 1.95117,1.9375 0,5.638672 2.8164,-2.820313 2.72657,2.796875 1.44531,-1.382812 -2.76758,-2.837891 0.0195,-0.02148 2.75977,-2.7460939 -5.5293,0.00977 -1.45898,-1.4433584 0,-4.5761719 -2,0 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         inkscape:connector-curvature="0" />
+      <path
+         sodipodi:nodetypes="ccccccccc"
+         inkscape:connector-curvature="0"
+         id="path4423"
+         d="m 404.21408,1046.5416 4.77734,-4.7461 0,-0.043 0.0371,0 0,-5.4023 -2,0 0,4.5762 -4.22852,4.2011 z"
+         style="fill:#000000;fill-opacity:0.5098038;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    </g>
+    <g
+       id="g4442"
+       transform="matrix(-1,0,0,1,840.01754,0)">
+      <path
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 407.0293,3.9882812 0,5.4023438 0.0371,0 0,0.042969 1.95117,1.9375 0,5.638672 2.8164,-2.820313 2.72657,2.796875 1.44531,-1.382812 -2.76758,-2.837891 0.0195,-0.02148 2.75977,-2.7460939 -5.5293,0.00977 -1.45898,-1.4433557 0,-4.5761719 -2,0 z"
+         transform="translate(0,1032.3622)"
+         id="path4444"
+         inkscape:connector-curvature="0" />
+      <path
+         style="fill:#000000;fill-opacity:0.5098038;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 404.21408,1046.5416 4.77734,-4.7461 0,-0.043 0.0371,0 0,-5.4023 -2,0 0,4.5762 -4.22852,4.2011 z"
+         id="path4447"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="ccccccccc" />
+    </g>
+    <g
+       id="g4465"
+       transform="translate(-0.99975,0)">
+      <path
+         sodipodi:nodetypes="ccccc"
+         inkscape:connector-curvature="0"
+         id="path4455"
+         d="m 449,1041.3622 4e-5,8 1.99996,0 -3e-5,-8 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+      <path
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 454.0156,1045.3622 4.9844,-5 -5,-5 z"
+         id="path4457"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccc" />
+      <path
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 455,1039.3466 -6,0 0,2 6,-10e-5 z"
+         id="path4461"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="ccccc" />
+      <path
+         sodipodi:nodetypes="ccccc"
+         inkscape:connector-curvature="0"
+         id="path4463"
+         d="m 451.01565,1039.3466 -7.9629,0 0,2 7.9629,-10e-5 z"
+         style="fill:#000000;fill-opacity:0.5098038;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    </g>
+    <path
+       sodipodi:nodetypes="ccccc"
+       inkscape:connector-curvature="0"
+       id="path4473"
+       d="m 472.053,1041.3622 -4e-5,8 -1.99996,0 3e-5,-8 z"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 467.0374,1045.3622 -4.9844,-5 5,-5 z"
+       id="path4475"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+    <path
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 466.053,1039.3466 6,0 0,2 -6,-10e-5 z"
+       id="path4477"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       sodipodi:nodetypes="ccccc"
+       inkscape:connector-curvature="0"
+       id="path4479"
+       d="m 470.03735,1039.3466 7.9629,0 0,2 -7.9629,-10e-5 z"
+       style="fill:#000000;fill-opacity:0.5098038;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 490,1036.3505 2.81445,2.8203 -4.77734,4.7461 0,0.043 -0.0371,0 0,5.4023 2,0 0,-4.5762 4.22852,-4.2011 2.77148,2.7773 0,-7 -7,-0.012 z"
+       id="path4491"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#000000;fill-opacity:0.50980392;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 490,1038.3622 -4e-5,11 -1.99996,0 3e-5,-11 z"
+       id="path4505"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path4510"
+       d="m 490,1036.3505 2.81445,2.8203 -4.77734,4.7461 0,0.043 -0.0371,0 0,5.4023 2,0 0,-4.5762 4.22852,-4.2011 2.77148,2.7773 0,-7 -7,-0.012 z"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path4514"
+       d="m 510.00001,1036.3505 -2.81445,2.8203 4.77734,4.7461 0,0.043 0.0371,0 0,5.4023 -2,0 0,-4.5762 -4.22852,-4.2011 -2.77148,2.7773 0,-7 7,-0.012 z"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="ccccc"
+       inkscape:connector-curvature="0"
+       id="path4516"
+       d="m 510.00001,1038.3622 4e-5,11 1.99996,0 -3e-5,-11 z"
+       style="fill:#000000;fill-opacity:0.5098038;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 510.00001,1036.3505 -2.81445,2.8203 4.77734,4.7461 0,0.043 0.0371,0 0,5.4023 -2,0 0,-4.5762 -4.22852,-4.2011 -2.77148,2.7773 0,-7 7,-0.012 z"
+       id="path4518"
+       inkscape:connector-curvature="0" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:'Times New Roman';-inkscape-font-specification:'Times New Roman';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="7.5"
+       y="1065.3622"
+       id="text4238"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan4240"
+         x="7.5"
+         y="1065.3622">0    1     2     3    4     5     6     7    8     9   10  11   12    13   14  15   16  17   18  19   20   21   22  23   24  25</tspan></text>
+    <path
+       inkscape:connector-curvature="0"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 170,1045.3622 c -1.10457,0 -2,0.8954 -2,2 0,1.1046 0.89543,2 2,2 1.10457,0 2,-0.8954 2,-2 0,-1.1046 -0.89543,-2 -2,-2 z"
+       id="path3440"
+       sodipodi:nodetypes="sssss" />
+  </g>
+</svg>
index 6f63efc2c95ac736b2676badb256ac1a73081c86..dd7147c74e1ad91ffb33d0f9ed0c4c6fd73ad031 100644 (file)
Binary files a/app/assets/images/wordpress.png and b/app/assets/images/wordpress.png differ
index a8fe29fce9d96cc75902762f8ab63b3954430ea6..15839a2ecbc4af23102a608c0804a4b988d92916 100644 (file)
@@ -18,18 +18,22 @@ window.onload = function () {
     args[parts[0]] = decodeURIComponent(parts[1] || '');
   }
 
+  var thunderforestOptions = {
+<% if defined?(THUNDERFOREST_KEY) %>
+    apikey: <%= THUNDERFOREST_KEY.to_json %>
+<% end %>
+  };
+
   var map = L.map("map");
   map.attributionControl.setPrefix('');
   map.removeControl(map.attributionControl);
 
-  if (!args.layer || args.layer === "mapnik" || args.layer === "osmarender") {
+  if (!args.layer || args.layer === "mapnik" || args.layer === "osmarender" || args.layer === "mapquest") {
     new L.OSM.Mapnik().addTo(map);
   } else if (args.layer === "cyclemap" || args.layer === "cycle map") {
-    new L.OSM.CycleMap().addTo(map);
+    new L.OSM.CycleMap(thunderforestOptions).addTo(map);
   } else if (args.layer === "transportmap") {
-    new L.OSM.TransportMap().addTo(map);
-  } else if (args.layer === "mapquest") {
-    new L.OSM.MapQuestOpen().addTo(map);
+    new L.OSM.TransportMap(thunderforestOptions).addTo(map);
   } else if (args.layer === "hot") {
     new L.OSM.HOT().addTo(map);
   }
index fdbeaba22fbc0bf50b96133405cc62c93d52d0c5..796a5f4d31d85f4ced3929b12cda6f091798cef3 100644 (file)
@@ -95,14 +95,25 @@ $(document).ready(function () {
   L.OSM.zoom({position: position})
     .addTo(map);
 
-  L.control.locate({
+  var locate = L.control.locate({
     position: position,
+    icon: 'icon geolocate',
+    iconLoading: 'icon geolocate',
     strings: {
       title: I18n.t('javascripts.map.locate.title'),
       popup: I18n.t('javascripts.map.locate.popup')
     }
   }).addTo(map);
 
+  var locateContainer = locate.getContainer();
+
+  $(locateContainer)
+    .removeClass('leaflet-control-locate leaflet-bar')
+    .addClass('control-locate')
+    .children("a")
+    .removeClass('leaflet-bar-part leaflet-bar-part-single')
+    .addClass('control-button');
+
   var sidebar = L.OSM.sidebar('#map-ui')
     .addTo(map);
 
@@ -161,17 +172,29 @@ $(document).ready(function () {
       map.getLayersCode(),
       map._object);
 
-    $.removeCookie("_osm_location");
-    $.cookie("_osm_location", OSM.locationCookie(map), { expires: expiry, path: "/" });
+    $.removeCookie('_osm_location');
+    $.cookie('_osm_location', OSM.locationCookie(map), { expires: expiry, path: '/' });
   });
 
   if ($.cookie('_osm_welcome') === 'hide') {
     $('.welcome').hide();
   }
 
-  $('.welcome .close').on('click', function() {
+  $('.welcome .close-wrap').on('click', function() {
     $('.welcome').hide();
-    $.cookie("_osm_welcome", 'hide', { expires: expiry });
+    $.cookie('_osm_welcome', 'hide', { expires: expiry, path: '/' });
+  });
+
+  var bannerExpiry = new Date();
+  bannerExpiry.setYear(bannerExpiry.getFullYear() + 1);
+
+  $('#banner .close-wrap').on('click', function(e) {
+    var cookieId = e.target.id;
+    $('#banner').hide();
+    e.preventDefault();
+    if (cookieId) {
+      $.cookie(cookieId, 'hide', { expires: bannerExpiry, path: '/' });
+    }
   });
 
   if (OSM.PIWIK) {
index c35085b35482fcbf336a7dd76c96522675affbb2..88a9c15c1215b00ae19ba6a7373eb88dff1efd7c 100644 (file)
@@ -1,15 +1,15 @@
 function GraphHopperEngine(id, vehicleType) {
   var GH_INSTR_MAP = {
-    "-3": 6, // sharp left
-    "-2": 7, // left
-    "-1": 8, // slight left
+    "-3": 7, // sharp left
+    "-2": 6, // left
+    "-1": 5, // slight left
     0: 0, // straight
     1: 1, // slight right
     2: 2, // right
     3: 3, // sharp right
-    4: -1, // finish reached
-    5: -1, // via reached
-    6: 11 // roundabout
+    4: 14, // finish reached
+    5: 14, // via reached
+    6: 10 // roundabout
   };
 
   return {
@@ -44,7 +44,7 @@ function GraphHopperEngine(id, vehicleType) {
           var len = path.instructions.length;
           for (var i = 0; i < len; i++) {
             var instr = path.instructions[i];
-            var instrCode = (i === len - 1) ? 15 : GH_INSTR_MAP[instr.sign];
+            var instrCode = (i === len - 1) ? 14 : GH_INSTR_MAP[instr.sign];
             var instrText = "<b>" + (i + 1) + ".</b> ";
             instrText += instr.text;
             var latLng = line[instr.interval[0]];
index 0f645ceeb7f35e621369d080517887f82154595d..fcc47f103544ed3e99943eb5df17c573b655a826 100644 (file)
@@ -5,25 +5,25 @@
 
 function MapQuestEngine(id, routeType) {
   var MQ_SPRITE_MAP = {
-    0: 1, // straight
-    1: 2, // slight right
-    2: 3, // right
-    3: 4, // sharp right
-    4: 5, // reverse
-    5: 6, // sharp left
-    6: 7, // left
-    7: 8, // slight left
-    8: 5, // right U-turn
-    9: 5, // left U-turn
-    10: 2, // right merge
-    11: 8, // left merge
-    12: 2, // right on-ramp
-    13: 8, // left on-ramp
-    14: 2, // right off-ramp
-    15: 8, // left off-ramp
-    16: 2, // right fork
-    17: 8, // left fork
-    18: 1  // straight fork
+    0: 0, // straight
+    1: 1, // slight right
+    2: 2, // right
+    3: 3, // sharp right
+    4: 4, // reverse
+    5: 7, // sharp left
+    6: 6, // left
+    7: 5, // slight left
+    8: 4, // right U-turn
+    9: 4, // left U-turn
+    10: 21, // right merge
+    11: 20, // left merge
+    12: 21, // right on-ramp
+    13: 20, // left on-ramp
+    14: 24, // right off-ramp
+    15: 25, // left off-ramp
+    16: 18, // right fork
+    17: 19, // left fork
+    18: 0  // straight fork
   };
 
   return {
index 1b775ba5106ffec7760c207e19261243ad719b11..263938860a04ec004403be4610da44a890e1f5b3 100644 (file)
@@ -1,35 +1,35 @@
 function MapzenEngine(id, costing) {
   var MZ_INSTR_MAP = [
-    1,  // kNone = 0;
-    14, // kStart = 1;
-    14, // kStartRight = 2;
-    14, // kStartLeft = 3;
-    15, // kDestination = 4;
-    15, // kDestinationRight = 5;
-    15, // kDestinationLeft = 6;
-    1,  // kBecomes = 7;
-    1,  // kContinue = 8;
-    2,  // kSlightRight = 9;
-    3,  // kRight = 10;
-    4,  // kSharpRight = 11;
-    5,  // kUturnRight = 12;
-    5,  // kUturnLeft = 13;
-    6,  // kSharpLeft = 14;
-    7,  // kLeft = 15;
-    8,  // kSlightLeft = 16;
-    1,  // kRampStraight = 17;
-    2 // kRampRight = 18;
-    8,  // kRampLeft = 19;
-    2 // kExitRight = 20;
-    8,  // kExitLeft = 21;
-    1,  // kStayStraight = 22;
-    2,  // kStayRight = 23;
-    8,  // kStayLeft = 24;
-    1,  // kMerge = 25;
-    11, // kRoundaboutEnter = 26;
-    12, // kRoundaboutExit = 27;
-    18, // kFerryEnter = 28;
-    1   // kFerryExit = 29;
+    0,  // kNone = 0;
+    8, // kStart = 1;
+    8, // kStartRight = 2;
+    8, // kStartLeft = 3;
+    14,  // kDestination = 4;
+    14,  // kDestinationRight = 5;
+    14,  // kDestinationLeft = 6;
+    0,  // kBecomes = 7;
+    0,  // kContinue = 8;
+    1,  // kSlightRight = 9;
+    2,  // kRight = 10;
+    3,  // kSharpRight = 11;
+    4,  // kUturnRight = 12;
+    4,  // kUturnLeft = 13;
+    7,  // kSharpLeft = 14;
+    6,  // kLeft = 15;
+    5,  // kSlightLeft = 16;
+    0,  // kRampStraight = 17;
+    24, // kRampRight = 18;
+    25, // kRampLeft = 19;
+    24, // kExitRight = 20;
+    25, // kExitLeft = 21;
+    0,  // kStayStraight = 22;
+    1,  // kStayRight = 23;
+    5,  // kStayLeft = 24;
+    20, // kMerge = 25;
+    10, // kRoundaboutEnter = 26;
+    11, // kRoundaboutExit = 27;
+    17, // kFerryEnter = 28;
+    0   // kFerryExit = 29;
   ];
 
   return {
@@ -46,7 +46,8 @@ function MapzenEngine(id, costing) {
             locations: points.map(function (p) { return { lat: p.lat, lon: p.lng }; }),
             costing: costing,
             directions_options: {
-              units: "km"
+              units: "km",
+              language: I18n.currentLocale()
             }
           })
         },
index 2ee9da12b1d78dbce1f057d9f706e5d4fa374692..6d2d5872ca3f9d5795c33b8ce70179bc10dc0420 100644 (file)
 // Doesn't yet support hints
 
 function OSRMEngine() {
-  var previousPoints, hintData;
+  var cachedHints = [];
 
   return {
     id: "osrm_car",
     creditline: '<a href="http://project-osrm.org/" target="_blank">OSRM</a>',
     draggable: true,
 
+    _transformSteps: function(input_steps, line) {
+      var INSTRUCTION_TEMPLATE = {
+        'continue': 'javascripts.directions.instructions.continue',
+        'merge right': 'javascripts.directions.instructions.merge_right',
+        'merge left': 'javascripts.directions.instructions.merge_left',
+        'off ramp right': 'javascripts.directions.instructions.offramp_right',
+        'off ramp left': 'javascripts.directions.instructions.offramp_left',
+        'on ramp right': 'javascripts.directions.instructions.onramp_right',
+        'on ramp left': 'javascripts.directions.instructions.onramp_left',
+        'fork right': 'javascripts.directions.instructions.fork_right',
+        'fork left': 'javascripts.directions.instructions.fork_left',
+        'end of road right': 'javascripts.directions.instructions.endofroad_right',
+        'end of road left': 'javascripts.directions.instructions.endofroad_left',
+        'turn straight': 'javascripts.directions.instructions.continue',
+        'turn slight right': 'javascripts.directions.instructions.slight_right',
+        'turn right': 'javascripts.directions.instructions.turn_right',
+        'turn sharp right': 'javascripts.directions.instructions.sharp_right',
+        'turn uturn': 'javascripts.directions.instructions.uturn',
+        'turn sharp left': 'javascripts.directions.instructions.sharp_left',
+        'turn left': 'javascripts.directions.instructions.turn_left',
+        'turn slight left': 'javascripts.directions.instructions.slight_left',
+        'trun straight': 'javascripts.directions.instructions.follow',
+        'roundabout': 'javascripts.directions.instructions.roundabout',
+        'rotary': 'javascripts.directions.instructions.roundabout',
+        'depart': 'javascripts.directions.instructions.start',
+        'arrive': 'javascripts.directions.instructions.destination',
+      };
+      var ICON_MAP = {
+        'continue': 0,
+        'merge right': 21,
+        'merge left': 20,
+        'off ramp right': 24,
+        'off ramp left': 25,
+        'on ramp right': 2,
+        'on ramp left': 6,
+        'fork right': 18,
+        'fork left': 19,
+        'end of road right': 22,
+        'end of road left': 23,
+        'turn straight': 0,
+        'turn slight right': 1,
+        'turn right': 2,
+        'turn sharp right': 3,
+        'turn uturn': 4,
+        'turn slight left': 5,
+        'turn left': 6,
+        'turn sharp left': 7,
+        'trun straight': 0,
+        'roundabout': 10,
+        'rotary': 10,
+        'depart': 8,
+        'arrive': 14
+      };
+      var transformed_steps = input_steps.map(function(step, idx) {
+        var maneuver_id;
+
+        // special case handling
+        switch (step.maneuver.type) {
+          case 'on ramp':
+          case 'off ramp':
+          case 'merge':
+          case 'end of road':
+          case 'fork':
+            maneuver_id = step.maneuver.type + ' ' + (step.maneuver.modifier.indexOf('left') >= 0 ? 'left' : 'right');
+            break;
+          case 'depart':
+          case 'arrive':
+          case 'roundabout':
+          case 'rotary':
+            maneuver_id = step.maneuver.type;
+            break;
+          case 'roundabout turn':
+          case 'turn':
+            maneuver_id = "turn " + step.maneuver.modifier;
+            break;
+          // for unknown types the fallback is turn
+          default:
+            maneuver_id = "turn " + step.maneuver.modifier;
+            break;
+        }
+        var template = INSTRUCTION_TEMPLATE[maneuver_id];
+
+        // convert lat,lng pairs to LatLng objects
+        var step_geometry = L.PolylineUtil.decode(step.geometry, { precision: 5 }).map(function(a) { return L.latLng(a); }) ;
+        // append step_geometry on line
+        Array.prototype.push.apply(line, step_geometry);
+
+        var instText = "<b>" + (idx + 1) + ".</b> ";
+        var name = step.name ? "<b>" + step.name + "</b>" : I18n.t('javascripts.directions.instructions.unnamed');
+        if (step.maneuver.type.match(/rotary|roundabout/)) {
+          instText += I18n.t(template + '_with_exit', { exit: step.maneuver.exit, name: name } );
+        } else {
+          instText += I18n.t(template + '_without_exit', { name: name });
+        }
+        return [[step.maneuver.location[1], step.maneuver.location[0]], ICON_MAP[maneuver_id], instText, step.distance, step_geometry];
+      });
+
+      return transformed_steps;
+    },
+
     getRoute: function (points, callback) {
-      var TURN_INSTRUCTIONS = [
-        "",
-        'javascripts.directions.instructions.continue',         // 1
-        'javascripts.directions.instructions.slight_right',     // 2
-        'javascripts.directions.instructions.turn_right',       // 3
-        'javascripts.directions.instructions.sharp_right',      // 4
-        'javascripts.directions.instructions.uturn',            // 5
-        'javascripts.directions.instructions.sharp_left',       // 6
-        'javascripts.directions.instructions.turn_left',        // 7
-        'javascripts.directions.instructions.slight_left',      // 8
-        'javascripts.directions.instructions.via_point',        // 9
-        'javascripts.directions.instructions.follow',           // 10
-        'javascripts.directions.instructions.roundabout',       // 11
-        'javascripts.directions.instructions.leave_roundabout', // 12
-        'javascripts.directions.instructions.stay_roundabout',  // 13
-        'javascripts.directions.instructions.start',            // 14
-        'javascripts.directions.instructions.destination',      // 15
-        'javascripts.directions.instructions.against_oneway',   // 16
-        'javascripts.directions.instructions.end_oneway',       // 17
-        'javascripts.directions.instructions.ferry'             // 18
-      ];
 
       var params = [
-        { name: "z", value: "14" },
-        { name: "output", value: "json" },
-        { name: "instructions", value: true }
+        { name: "overview", value: "false" },
+        { name: "geometries", value: "polyline" },
+        { name: "steps", value: true }
       ];
 
-      for (var i = 0; i < points.length; i++) {
-        params.push({ name: "loc", value: points[i].lat + "," + points[i].lng });
 
-        if (hintData && previousPoints && previousPoints[i].equals(points[i])) {
-          params.push({ name: "hint", value: hintData.locations[i] });
-        }
+      if (cachedHints.length === points.length) {
+        params.push({name: "hints", value: cachedHints.join(";")});
+      } else {
+        // invalidate cache
+        cachedHints = [];
       }
 
-      if (hintData && hintData.checksum) {
-        params.push({ name: "checksum", value: hintData.checksum });
-      }
+      var encoded_coords = points.map(function(p) {
+        return p.lng + ',' + p.lat;
+      }).join(';');
+
+      var req_url = document.location.protocol + OSM.OSRM_URL + encoded_coords;
+
+      var onResponse = function (data) {
+        if (data.code !== 'Ok')
+          return callback(true);
+
+        cachedHints = data.waypoints.map(function(wp) {
+          return wp.hint;
+        });
+
+        var line = [];
+        var transformLeg = function (leg) {
+          return this._transformSteps(leg.steps, line);
+        };
+
+        var steps = [].concat.apply([], data.routes[0].legs.map(transformLeg.bind(this)));
+
+        callback(false, {
+          line: line,
+          steps: steps,
+          distance: data.routes[0].distance,
+          time: data.routes[0].duration
+        });
+      };
 
       return $.ajax({
-        url: document.location.protocol + OSM.OSRM_URL,
+        url: req_url,
         data: params,
         dataType: "json",
-        success: function (data) {
-          if (data.status === 207)
-            return callback(true);
-
-          previousPoints = points;
-          hintData = data.hint_data;
-
-          var line = L.PolylineUtil.decode(data.route_geometry, {
-            precision: 6
-          });
-
-          var steps = [];
-          for (i = 0; i < data.route_instructions.length; i++) {
-            var s = data.route_instructions[i];
-            var linesegend;
-            var instCodes = s[0].split('-');
-            if (s[8] === 2) {
-              /* indicates a ferry in car routing mode, see https://github.com/Project-OSRM/osrm-backend/blob/6cbbd1e5a1b441eb27055f56956e1bac14832a58/profiles/car.lua#L151 */
-              instCodes = ["18"];
-            }
-            var instText = "<b>" + (i + 1) + ".</b> ";
-            var name = s[1] ? "<b>" + s[1] + "</b>" : I18n.t('javascripts.directions.instructions.unnamed');
-            if (instCodes[0] === "11" && instCodes[1]) {
-              instText += I18n.t(TURN_INSTRUCTIONS[instCodes[0]] + '_with_exit', { exit: instCodes[1], name: name } );
-            } else {
-              instText += I18n.t(TURN_INSTRUCTIONS[instCodes[0]] + '_without_exit', { name: name });
-            }
-            if ((i + 1) < data.route_instructions.length) {
-              linesegend = data.route_instructions[i + 1][3] + 1;
-            } else {
-              linesegend = s[3] + 1;
-            }
-            steps.push([line[s[3]], instCodes[0], instText, s[2], line.slice(s[3], linesegend)]);
-          }
-
-          callback(false, {
-            line: line,
-            steps: steps,
-            distance: data.route_summary.total_distance,
-            time: data.route_summary.total_time
-          });
-        },
+        success: onResponse.bind(this),
         error: function () {
           callback(true);
         }
index 9481e271e9565446c9e1abee595f531a0ec1a3c5..52af38c54f338b1d76290f8195108d48a0cf5de9 100644 (file)
@@ -95,15 +95,18 @@ OSM.Search = function(map) {
     $(this).closest("li").removeClass("selected");
   }
 
-  function clickSearchResult(e) {
-    var data = $(this).data(),
-      center = L.latLng(data.lat, data.lon);
-
+  function panToSearchResult(data) {
     if (data.minLon && data.minLat && data.maxLon && data.maxLat) {
       map.fitBounds([[data.minLat, data.minLon], [data.maxLat, data.maxLon]]);
     } else {
-      map.setView(center, data.zoom);
+      map.setView([data.lat, data.lon], data.zoom);
     }
+  }
+
+  function clickSearchResult(e) {
+    var data = $(this).data();
+
+    panToSearchResult(data);
 
     // Let clicks to object browser links propagate.
     if (data.type && data.id) return;
@@ -124,7 +127,7 @@ OSM.Search = function(map) {
   };
 
   page.load = function() {
-    $(".search_results_entry").each(function() {
+    $(".search_results_entry").each(function(index) {
       var entry = $(this);
       $.ajax({
         url: entry.data("href"),
@@ -138,6 +141,13 @@ OSM.Search = function(map) {
         },
         success: function(html) {
           entry.html(html);
+          // go to first result of first geocoder
+          if (index === 0) {
+            var firstResult = entry.find('*[data-lat][data-lon]:first').first();
+            if (firstResult.length) {
+              panToSearchResult(firstResult.data());
+            }
+          }
         }
       });
     });
index 68e822e7f3504409d41380abc9b9be2af159325d..5223b1420523fd58770177ea66dca42946483d17 100644 (file)
@@ -60,7 +60,7 @@ L.OSM.key = function (options) {
     }
 
     function updateButton() {
-      var disabled = map.getMapBaseLayerId() !== 'mapnik';
+      var disabled = ['mapnik', 'cyclemap'].indexOf(map.getMapBaseLayerId()) === -1;
       button
         .toggleClass('disabled', disabled)
         .attr('data-original-title',
index 9f2e50a6f4afaa928cb6c1611b24843708cabd09..c294f13ef2ef749065a4753e3a0e5f13a369a03b 100644 (file)
@@ -50,7 +50,7 @@ L.OSM.layers = function(options) {
 
       map.whenReady(function() {
         var miniMap = L.map(div[0], {attributionControl: false, zoomControl: false})
-          .addLayer(new layer.constructor());
+          .addLayer(new layer.constructor({ apikey: layer.options.apikey }));
 
         miniMap.dragging.disable();
         miniMap.touchZoom.disable();
index 58360bbec57513bbd738db621ab79bca00008cd2..4f3c7bc25d711561e9c1432b5a3c10a88faf5ca8 100644 (file)
@@ -16,38 +16,39 @@ L.OSM.Map = L.Map.extend({
     var copyright = I18n.t('javascripts.map.copyright', {copyright_url: '/copyright'});
     var donate = I18n.t('javascripts.map.donate_link_text', {donate_url: 'http://donate.openstreetmap.org'});
 
-    this.baseLayers = [
-      new L.OSM.Mapnik({
-        attribution: copyright + " &hearts; " + donate,
-        code: "M",
-        keyid: "mapnik",
-        name: I18n.t("javascripts.map.base.standard")
-      }),
-      new L.OSM.CycleMap({
+    this.baseLayers = [];
+
+    this.baseLayers.push(new L.OSM.Mapnik({
+      attribution: copyright + " &hearts; " + donate,
+      code: "M",
+      keyid: "mapnik",
+      name: I18n.t("javascripts.map.base.standard")
+    }));
+
+    if (OSM.THUNDERFOREST_KEY) {
+      this.baseLayers.push(new L.OSM.CycleMap({
         attribution: copyright + ". Tiles courtesy of <a href='http://www.thunderforest.com/' target='_blank'>Andy Allan</a>",
+        apikey: OSM.THUNDERFOREST_KEY,
         code: "C",
         keyid: "cyclemap",
         name: I18n.t("javascripts.map.base.cycle_map")
-      }),
-      new L.OSM.TransportMap({
+      }));
+
+      this.baseLayers.push(new L.OSM.TransportMap({
         attribution: copyright + ". Tiles courtesy of <a href='http://www.thunderforest.com/' target='_blank'>Andy Allan</a>",
+        apikey: OSM.THUNDERFOREST_KEY,
         code: "T",
         keyid: "transportmap",
         name: I18n.t("javascripts.map.base.transport_map")
-      }),
-      new L.OSM.MapQuestOpen({
-        attribution: copyright + ". Tiles courtesy of <a href='http://www.mapquest.com/' target='_blank'>MapQuest</a> <img src='https://developer.mapquest.com/content/osm/mq_logo.png'>",
-        code: "Q",
-        keyid: "mapquest",
-        name: I18n.t("javascripts.map.base.mapquest")
-      }),
-      new L.OSM.HOT({
-        attribution: copyright + ". Tiles courtesy of <a href='http://hot.openstreetmap.org/' target='_blank'>Humanitarian OpenStreetMap Team</a>",
-        code: "H",
-        keyid: "hot",
-        name: I18n.t("javascripts.map.base.hot")
-      })
-    ];
+      }));
+    }
+
+    this.baseLayers.push(new L.OSM.HOT({
+      attribution: copyright + ". Tiles courtesy of <a href='http://hot.openstreetmap.org/' target='_blank'>Humanitarian OpenStreetMap Team</a>",
+      code: "H",
+      keyid: "hot",
+      name: I18n.t("javascripts.map.base.hot")
+    }));
 
     this.noteLayer = new L.FeatureGroup();
     this.noteLayer.options = {code: 'N'};
@@ -276,7 +277,7 @@ L.OSM.Map = L.Map.extend({
   }
 });
 
-L.Icon.Default.imagePath = "/images";
+L.Icon.Default.imagePath = "/images/";
 
 L.Icon.Default.imageUrls = {
   "/images/marker-icon.png": OSM.MARKER_ICON,
index 138416be12525fa1fb1480c3e5151f69ffb76daa..10b7cfdb81cda46676c9d397ded0d558fcf61af6 100644 (file)
@@ -23,6 +23,9 @@ OSM = {
 <% if defined?(MAPZEN_VALHALLA_KEY) %>
   MAPZEN_VALHALLA_KEY:     <%= MAPZEN_VALHALLA_KEY.to_json %>,
 <% end %>
+<% if defined?(THUNDERFOREST_KEY) %>
+  THUNDERFOREST_KEY:       <%= THUNDERFOREST_KEY.to_json %>,
+<% end %>
 
   MARKER_GREEN:            <%= image_path("marker-green.png").to_json %>,
   MARKER_RED:              <%= image_path("marker-red.png").to_json %>,
index e8ad3324d0ccc2b01e5a4e3b388b39f0d47f6603..7e7e7c8032a6cbab6d9018d7d0ee888eb0dd0df2 100644 (file)
@@ -12,14 +12,25 @@ $(document).ready(function () {
     L.OSM.zoom({position: position})
       .addTo(map);
 
-    L.control.locate({
+    var locate = L.control.locate({
       position: position,
+      icon: 'icon geolocate',
+      iconLoading: 'icon geolocate',
       strings: {
         title: I18n.t('javascripts.map.locate.title'),
         popup: I18n.t('javascripts.map.locate.popup')
       }
     }).addTo(map);
 
+    var locateContainer = locate.getContainer();
+
+    $(locateContainer)
+      .removeClass('leaflet-control-locate leaflet-bar')
+      .addClass('control-locate')
+      .children("a")
+      .removeClass('leaflet-bar-part leaflet-bar-part-single')
+      .addClass('control-button');
+
     if (OSM.home) {
       map.setView([OSM.home.lat, OSM.home.lon], 12);
     } else {
index cf687653e1efa19bd18fd82ddf7ad20d4aec8055..4529248c58f134b5925b3c829135899433771efb 100644 (file)
@@ -173,6 +173,7 @@ small, aside {
 .icon.clipboard   { background-position: -160px 0; }
 .icon.link        { background-position: -180px 0; }
 .icon.close       { background-position: -200px 0; }
+.close-wrap:hover .icon.close,
 .icon.close:hover { background-position: -200px -20px; }
 .icon.check       { background-position: -220px 0; }
 .icon.note        { background-position: -240px 0; }
@@ -546,6 +547,13 @@ body.compact {
     background: #fff;
     font-size: 12px;
 
+    > div {
+      position: relative;
+      float: left;
+      clear: both;
+      width: 100%;
+    }
+
     h2 {
       padding: $lineheight $lineheight $lineheight/2;
     }
@@ -556,6 +564,22 @@ body.compact {
       font-size: 13px;
     }
 
+    .close-wrap {
+      cursor: pointer;
+      position: absolute;
+      top: 0;
+      right: 0;
+      width: 60px;
+      height: 60px;
+
+      .icon.close {
+        pointer-events: none;
+        position: absolute;
+        right: 20px;
+        top: 20px;
+      }
+    }
+
     .icon.close {
       float: right;
       cursor: pointer;
@@ -568,25 +592,26 @@ body.compact {
     }
   }
 
-  .welcome {
-    display: none;
-  }
-
   .overlay-sidebar #sidebar {
     position: absolute;
     z-index: 1000;
     height: auto;
-    border-bottom-right-radius: 5px;
     overflow: hidden;
+
+    #banner,
     .welcome {
       display: block;
     }
+
     #sidebar_content {
       display: none;
     }
   }
 
   .welcome {
+    display: none;
+    padding-bottom: 5px;
+
     p {
       padding: $lineheight/2 $lineheight $lineheight;
       font-size: 110%;
@@ -607,6 +632,15 @@ body.compact {
     }
   }
 
+  #banner {
+    display: none;
+
+    img {
+      display: block;
+      width: $sidebarWidth;
+    }
+  }
+
   #map {
     height: 100%;
     overflow: hidden;
@@ -691,7 +725,7 @@ body.compact {
         font-size: 16px;
         text-stroke: 2px #fff;
         background: rgba(255,255,255,.9);
-        z-index: 2; // For IE9
+        z-index: 1000;
         input[type="radio"] {
           display: none;
         }
@@ -836,10 +870,15 @@ body.compact {
 
 #sidebar {
   #sidebar_loader,
+  .search_more {
+    width: 100%;
+    margin: $lineheight auto;
+  }
+
   .loader,
   .load_more {
     text-align: center;
-    margin: $lineheight auto;
+    margin: auto;
     width: 40px;
     display: block;
   }
@@ -1003,8 +1042,8 @@ div.direction {
   height: 20px;
   background-repeat: no-repeat;
 }
-@for $i from 1 through 18 {
-div.direction.i#{$i} { background-position: #{($i)*-20+20}px 0px; }
+@for $i from 0 through 25 {
+div.direction.i#{$i} { background-position: #{($i)*-20}px 0px; }
 }
 
 p#routing_summary {
@@ -1641,6 +1680,13 @@ tr.turn:hover {
   float: left;
 }
 
+
+.diary-subscribe-buttons {
+  position:relative;
+  top: -30px;
+  left: 130px;
+}
+
 /* Rules for the log in page */
 
 #login_auth_buttons {
index c05c73c9d8b92825ae50fb6d59d7d5babdc8bbf3..984364736b35290d8cb38a272f1016711d6bdf22 100644 (file)
@@ -126,13 +126,13 @@ body.small {
     }
   }
 
-  #sidebar .welcome {
+  #sidebar .welcome,
+  #sidebar #banner {
     display: none !important;
   }
 
   .leaflet-top.leaflet-right {
     top: 10px !important;
-    z-index: 0;
   }
 
   .content_map {
index 9cd6857483982e89cb8c5feec0098ee774a540d2..632974f4fa28042412b832cf2754d9500982f0d9 100644 (file)
@@ -86,14 +86,14 @@ class AmfController < ApplicationController
           orn = renumberednodes.dup
           result = putway(renumberednodes, *args)
           result[4] = renumberednodes.reject { |k, _v| orn.key?(k) }
-          renumberedways[result[2]] = result[3] if result[0] == 0 && result[2] != result[3]
+          renumberedways[result[2]] = result[3] if result[0].zero? && result[2] != result[3]
         when "putrelation" then
           result = putrelation(renumberednodes, renumberedways, *args)
         when "deleteway" then
           result = deleteway(*args)
         when "putpoi" then
           result = putpoi(*args)
-          renumberednodes[result[2]] = result[3] if result[0] == 0 && result[2] != result[3]
+          renumberednodes[result[2]] = result[3] if result[0].zero? && result[2] != result[3]
         when "startchangeset" then
           result = startchangeset(*args)
         end
@@ -163,7 +163,7 @@ class AmfController < ApplicationController
       end
 
       # open a new changeset
-      if opennew != 0
+      if opennew.nonzero?
         cs = Changeset.new
         cs.tags = cstags
         cs.user_id = user.id
@@ -540,7 +540,7 @@ class AmfController < ApplicationController
       tags = strip_non_xml_chars tags
 
       relid = relid.to_i
-      visible = (visible.to_i != 0)
+      visible = visible.to_i.nonzero?
 
       new_relation = nil
       relation = nil
@@ -644,7 +644,7 @@ class AmfController < ApplicationController
           id = a[2].to_i
           version = a[3].to_i
 
-          return -2, "Server error - node with id 0 found in way #{originalway}." if id == 0
+          return -2, "Server error - node with id 0 found in way #{originalway}." if id.zero?
           return -2, "Server error - node with latitude -90 found in way #{originalway}." if lat == 90
 
           id = renumberednodes[id] if renumberednodes[id]
@@ -868,7 +868,7 @@ class AmfController < ApplicationController
 
   def getuser(token) #:doc:
     if token =~ /^(.+)\:(.+)$/
-      User.authenticate(:username => $1, :password => $2)
+      User.authenticate(:username => Regexp.last_match(1), :password => Regexp.last_match(2))
     else
       User.authenticate(:token => token)
     end
@@ -914,7 +914,7 @@ class AmfController < ApplicationController
     INNER JOIN current_ways  ON current_ways.id =current_way_nodes.id
        WHERE current_nodes.visible=TRUE
        AND current_ways.visible=TRUE
-       AND #{OSM.sql_for_area(bbox, "current_nodes.")}
+       AND #{OSM.sql_for_area(bbox, 'current_nodes.')}
     EOF
     ActiveRecord::Base.connection.select_all(sql).collect { |a| [a["wayid"].to_i, a["version"].to_i] }
   end
@@ -927,7 +927,7 @@ class AmfController < ApplicationController
        LEFT OUTER JOIN current_way_nodes cwn ON cwn.node_id=current_nodes.id
        WHERE current_nodes.visible=TRUE
        AND cwn.id IS NULL
-       AND #{OSM.sql_for_area(bbox, "current_nodes.")}
+       AND #{OSM.sql_for_area(bbox, 'current_nodes.')}
     EOF
     ActiveRecord::Base.connection.select_all(sql).each do |row|
       poitags = {}
@@ -947,7 +947,7 @@ class AmfController < ApplicationController
       FROM current_relations cr
       INNER JOIN current_relation_members crm ON crm.id=cr.id
       INNER JOIN current_nodes cn ON crm.member_id=cn.id AND crm.member_type='Node'
-       WHERE #{OSM.sql_for_area(bbox, "cn.")}
+       WHERE #{OSM.sql_for_area(bbox, 'cn.')}
       EOF
     unless way_ids.empty?
       sql += <<-EOF
index 25e1e3b95cc9edebaff056d1ea9fdbcf5ca22f98..eb59a8a8df0bda5da97d218ceee62bd99ed4393d 100644 (file)
@@ -300,10 +300,9 @@ class ApiController < ApplicationController
   # * if authenticated via basic auth all permissions are granted, so the list will contain all permissions.
   # * unauthenticated users have no permissions, so the list will be empty.
   def permissions
-    @permissions = case
-                   when current_token.present?
+    @permissions = if current_token.present?
                      ClientApplication.all_permissions.select { |p| current_token.read_attribute(p) }
-                   when @user
+                   elsif @user
                      ClientApplication.all_permissions
                    else
                      []
index f3b77f8108acade06c00f70a367a3f6f606cd2f1..0c50276b61ba040d7efb86843633f93e38a9dd31 100644 (file)
@@ -62,7 +62,7 @@ class ApplicationController < ActionController::Base
     unless current_token.nil?
       unless current_token.read_attribute(cap)
         report_error "OAuth token doesn't have that capability.", :forbidden
-        return false
+        false
       end
     end
   end
@@ -74,7 +74,7 @@ class ApplicationController < ActionController::Base
       if params[:cookie_test].nil?
         session[:cookie_test] = true
         redirect_to Hash[params].merge(:cookie_test => "true")
-        return false
+        false
       else
         flash.now[:warning] = t "application.require_cookies.cookies_needed"
       end
@@ -192,7 +192,7 @@ class ApplicationController < ActionController::Base
     # check user is a moderator
     unless @user.moderator?
       render :text => errormessage, :status => :forbidden
-      return false
+      false
     end
   end
 
@@ -220,14 +220,14 @@ class ApplicationController < ActionController::Base
   def check_api_readable
     if api_status == :offline
       report_error "Database offline for maintenance", :service_unavailable
-      return false
+      false
     end
   end
 
   def check_api_writable
     unless api_status == :online
       report_error "Database offline for maintenance", :service_unavailable
-      return false
+      false
     end
   end
 
@@ -262,7 +262,7 @@ class ApplicationController < ActionController::Base
   def require_public_data
     unless @user.data_public?
       report_error "You must make your edits public to upload new data", :forbidden
-      return false
+      false
     end
   end
 
@@ -375,7 +375,7 @@ class ApplicationController < ActionController::Base
   ##
   # ensure that there is a "this_user" instance variable
   def lookup_this_user
-    unless @this_user = User.active.find_by_display_name(params[:display_name])
+    unless @this_user = User.active.find_by(:display_name => params[:display_name])
       render_unknown_user params[:display_name]
     end
   end
index 89ba5d1313efabfda84b5e9a89132e0412a4364e..da066a73afa4bc703f293067ad536ea7c63536e7 100644 (file)
@@ -83,7 +83,7 @@ class ChangesetController < ApplicationController
 
     # the request is in pseudo-osm format... this is kind-of an
     # abuse, maybe should change to some other format?
-    doc = XML::Parser.string(request.raw_post).parse
+    doc = XML::Parser.string(request.raw_post, :options => XML::Parser::Options::NOERROR).parse
     doc.find("//osm/node").each do |n|
       lon << n["lon"].to_f * GeoRecord::SCALE
       lat << n["lat"].to_f * GeoRecord::SCALE
@@ -256,7 +256,7 @@ class ChangesetController < ApplicationController
     end
 
     if params[:display_name]
-      user = User.find_by_display_name(params[:display_name])
+      user = User.find_by(:display_name => params[:display_name])
       if !user || !user.active?
         render_unknown_user params[:display_name]
         return
@@ -481,7 +481,7 @@ class ChangesetController < ApplicationController
             raise OSM::APIBadUserInput.new("invalid user ID") if user.to_i < 1
             u = User.find(user.to_i)
           else
-            u = User.find_by_display_name(name)
+            u = User.find_by(:display_name => name)
           end
 
       # make sure we found a user
@@ -535,10 +535,10 @@ class ChangesetController < ApplicationController
   # if parameter 'open' is nill then open and closed changesets are returned
   def conditions_open(changesets, open)
     if open.nil?
-      return changesets
+      changesets
     else
-      return changesets.where("closed_at >= ? and num_changes <= ?",
-                              Time.now.getutc, Changeset::MAX_ELEMENTS)
+      changesets.where("closed_at >= ? and num_changes <= ?",
+                       Time.now.getutc, Changeset::MAX_ELEMENTS)
     end
   end
 
@@ -547,10 +547,10 @@ class ChangesetController < ApplicationController
   # ('closed at' time has passed or changes limit is hit)
   def conditions_closed(changesets, closed)
     if closed.nil?
-      return changesets
+      changesets
     else
-      return changesets.where("closed_at < ? or num_changes > ?",
-                              Time.now.getutc, Changeset::MAX_ELEMENTS)
+      changesets.where("closed_at < ? or num_changes > ?",
+                       Time.now.getutc, Changeset::MAX_ELEMENTS)
     end
   end
 
@@ -559,12 +559,12 @@ class ChangesetController < ApplicationController
   # (either specified as array or comma-separated string)
   def conditions_ids(changesets, ids)
     if ids.nil?
-      return changesets
+      changesets
     elsif ids.empty?
       raise OSM::APIBadUserInput.new("No changesets were given to search for")
     else
       ids = ids.split(",").collect(&:to_i)
-      return changesets.where(:id => ids)
+      changesets.where(:id => ids)
     end
   end
 
index c0b6ece3843dca44b75a415059815e9c92b3e7bd..61d95ba11b9f7fffe891c18915b4e78383a70f7e 100644 (file)
@@ -3,10 +3,10 @@ class DiaryEntryController < ApplicationController
 
   before_action :authorize_web
   before_action :set_locale
-  before_action :require_user, :only => [:new, :edit, :comment, :hide, :hidecomment]
+  before_action :require_user, :only => [:new, :edit, :comment, :hide, :hidecomment, :subscribe, :unsubscribe]
   before_action :lookup_this_user, :only => [:view, :comments]
   before_action :check_database_readable
-  before_action :check_database_writable, :only => [:new, :edit]
+  before_action :check_database_writable, :only => [:new, :edit, :comment, :hide, :hidecomment, :subscribe, :unsubscribe]
   before_action :require_administrator, :only => [:hide, :hidecomment]
 
   def new
@@ -24,7 +24,11 @@ class DiaryEntryController < ApplicationController
         else
           @user.preferences.create(:k => "diary.default_language", :v => @diary_entry.language_code)
         end
-        redirect_to :controller => "diary_entry", :action => "list", :display_name => @user.display_name
+
+        # Subscribe user to diary comments
+        @diary_entry.subscriptions.create(:user => @user)
+
+        redirect_to :action => "list", :display_name => @user.display_name
       else
         render :action => "edit"
       end
@@ -42,9 +46,9 @@ class DiaryEntryController < ApplicationController
     @diary_entry = DiaryEntry.find(params[:id])
 
     if @user != @diary_entry.user
-      redirect_to :controller => "diary_entry", :action => "view", :id => params[:id]
+      redirect_to :action => "view", :id => params[:id]
     elsif params[:diary_entry] && @diary_entry.update_attributes(entry_params)
-      redirect_to :controller => "diary_entry", :action => "view", :id => params[:id]
+      redirect_to :action => "view", :id => params[:id]
     end
 
     set_map_location
@@ -57,11 +61,18 @@ class DiaryEntryController < ApplicationController
     @diary_comment = @entry.comments.build(comment_params)
     @diary_comment.user = @user
     if @diary_comment.save
-      if @diary_comment.user != @entry.user
-        Notifier.diary_comment_notification(@diary_comment).deliver_now
+
+      # Notify current subscribers of the new comment
+      @entry.subscribers.visible.each do |user|
+        if @user != user
+          Notifier.diary_comment_notification(@diary_comment, user).deliver_now
+        end
       end
 
-      redirect_to :controller => "diary_entry", :action => "view", :display_name => @entry.user.display_name, :id => @entry.id
+      # Add the commenter to the subscribers if necessary
+      @entry.subscriptions.create(:user => @user) unless @entry.subscribers.exists?(@user.id)
+
+      redirect_to :action => "view", :display_name => @entry.user.display_name, :id => @entry.id
     else
       render :action => "view"
     end
@@ -69,9 +80,29 @@ class DiaryEntryController < ApplicationController
     render :action => "no_such_entry", :status => :not_found
   end
 
+  def subscribe
+    diary_entry = DiaryEntry.find(params[:id])
+
+    diary_entry.subscriptions.create(:user => @user) unless diary_entry.subscribers.exists?(@user.id)
+
+    redirect_to :action => "view", :display_name => diary_entry.user.display_name, :id => diary_entry.id
+  rescue ActiveRecord::RecordNotFound
+    render :action => "no_such_entry", :status => :not_found
+  end
+
+  def unsubscribe
+    diary_entry = DiaryEntry.find(params[:id])
+
+    diary_entry.subscriptions.where(:user => @user).delete_all if diary_entry.subscribers.exists?(@user.id)
+
+    redirect_to :action => "view", :display_name => diary_entry.user.display_name, :id => diary_entry.id
+  rescue ActiveRecord::RecordNotFound
+    render :action => "no_such_entry", :status => :not_found
+  end
+
   def list
     if params[:display_name]
-      @this_user = User.active.find_by_display_name(params[:display_name])
+      @this_user = User.active.find_by(:display_name => params[:display_name])
 
       if @this_user
         @title = t "diary_entry.list.user_title", :user => @this_user.display_name
@@ -119,7 +150,7 @@ class DiaryEntryController < ApplicationController
 
   def rss
     if params[:display_name]
-      user = User.active.find_by_display_name(params[:display_name])
+      user = User.active.find_by(:display_name => params[:display_name])
 
       if user
         @entries = user.diary_entries
@@ -201,7 +232,7 @@ class DiaryEntryController < ApplicationController
   def require_administrator
     unless @user.administrator?
       flash[:error] = t("user.filter.not_an_administrator")
-      redirect_to :controller => "diary_entry", :action => "view"
+      redirect_to :action => "view"
     end
   end
 
index 8afa80d7fbe593820b0f87ef7f6b92cf780f3e2b..57f86ec9fc7dd704d1b3e1d6347a1b6b28f8bbfd 100644 (file)
@@ -149,7 +149,7 @@ class GeocoderController < ApplicationController
     exclude = "&exclude_place_ids=#{params[:exclude]}" if params[:exclude]
 
     # ask nominatim
-    response = fetch_xml("http:#{NOMINATIM_URL}search?format=xml&q=#{escape_query(query)}#{viewbox}#{exclude}&accept-language=#{http_accept_language.user_preferred_languages.join(',')}")
+    response = fetch_xml("http:#{NOMINATIM_URL}search?format=xml&extratags=1&q=#{escape_query(query)}#{viewbox}#{exclude}&accept-language=#{http_accept_language.user_preferred_languages.join(',')}")
 
     # extract the results from the response
     results =  response.elements["searchresults"]
@@ -179,6 +179,11 @@ class GeocoderController < ApplicationController
       if klass == "boundary" && type == "administrative"
         rank = (place.attributes["place_rank"].to_i + 1) / 2
         prefix_name = t "geocoder.search_osm_nominatim.admin_levels.level#{rank}", :default => prefix_name
+        place.elements["extratags"].elements.each("tag") do |extratag|
+          if extratag.attributes["key"] == "place"
+            prefix_name = t "geocoder.search_osm_nominatim.prefix.place.#{extratag.attributes['value']}", :default => prefix_name
+          end
+        end
       end
       prefix = t "geocoder.search_osm_nominatim.prefix_format", :name => prefix_name
       object_type = place.attributes["osm_type"]
index a22802e63accdbe85531db1d740ba87df6a683f4..97e892156f097cc1a0cb22d51806ff5ec7efed4e 100644 (file)
@@ -25,7 +25,7 @@ class MessageController < ApplicationController
         if @message.save
           flash[:notice] = t "message.new.message_sent"
           Notifier.message_notification(@message).deliver_now
-          redirect_to :controller => "message", :action => "inbox", :display_name => @user.display_name
+          redirect_to :action => "inbox", :display_name => @user.display_name
         end
       end
     end
@@ -81,7 +81,7 @@ class MessageController < ApplicationController
     @title = t "message.inbox.title"
     if @user && params[:display_name] == @user.display_name
     else
-      redirect_to :controller => "message", :action => "inbox", :display_name => @user.display_name
+      redirect_to :action => "inbox", :display_name => @user.display_name
     end
   end
 
@@ -90,7 +90,7 @@ class MessageController < ApplicationController
     @title = t "message.outbox.title"
     if @user && params[:display_name] == @user.display_name
     else
-      redirect_to :controller => "message", :action => "outbox", :display_name => @user.display_name
+      redirect_to :action => "outbox", :display_name => @user.display_name
     end
   end
 
@@ -107,7 +107,7 @@ class MessageController < ApplicationController
     @message.message_read = message_read
     if @message.save && !request.xhr?
       flash[:notice] = notice
-      redirect_to :controller => "message", :action => "inbox", :display_name => @user.display_name
+      redirect_to :action => "inbox", :display_name => @user.display_name
     end
   rescue ActiveRecord::RecordNotFound
     @title = t "message.no_such_message.title"
@@ -125,7 +125,7 @@ class MessageController < ApplicationController
       if params[:referer]
         redirect_to params[:referer]
       else
-        redirect_to :controller => "message", :action => "inbox", :display_name => @user.display_name
+        redirect_to :action => "inbox", :display_name => @user.display_name
       end
     end
   rescue ActiveRecord::RecordNotFound
index 51ef4491d35363be75437919e9089537f1eeff9a..fde27e8b29e05dd1a512a5e15989bb1c0dcb0127 100644 (file)
@@ -127,7 +127,7 @@ class NotesController < ApplicationController
     comment = params[:text]
 
     # Find the note and check it is valid
-    @note = Note.find_by_id(id)
+    @note = Note.find_by(:id => id)
     raise OSM::APINotFoundError unless @note
     raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
     raise OSM::APINoteAlreadyClosedError.new(@note) if @note.closed?
@@ -157,7 +157,7 @@ class NotesController < ApplicationController
     comment = params[:text]
 
     # Find the note and check it is valid
-    @note = Note.find_by_id(id)
+    @note = Note.find_by(:id => id)
     raise OSM::APINotFoundError unless @note
     raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible? || @user.moderator?
     raise OSM::APINoteAlreadyOpenError.new(@note) unless @note.closed? || !@note.visible?
@@ -277,7 +277,7 @@ class NotesController < ApplicationController
   # Display a list of notes by a specified user
   def mine
     if params[:display_name]
-      if @this_user = User.active.find_by_display_name(params[:display_name])
+      if @this_user = User.active.find_by(:display_name => params[:display_name])
         @title = t "note.mine.title", :user => @this_user.display_name
         @heading = t "note.mine.heading", :user => @this_user.display_name
         @description = t "note.mine.subheading", :user => render_to_string(:partial => "user", :object => @this_user)
@@ -316,7 +316,7 @@ class NotesController < ApplicationController
   end
 
   ##
-  # Generate a condition to choose which bugs we want based
+  # Generate a condition to choose which notes we want based
   # on their status and the user's request parameters
   def closed_condition(notes)
     closed_since = if params[:closed]
index 59ebfd631b0075d1279a6738bf55a9278713602c..2e847fcd5915e9b954c85ae5c87774a55e87e0ff 100644 (file)
@@ -27,7 +27,7 @@ class OauthController < ApplicationController
   end
 
   def revoke
-    @token = current_user.oauth_tokens.find_by_token params[:token]
+    @token = current_user.oauth_tokens.find_by :token => params[:token]
     if @token
       @token.invalidate!
       flash[:notice] = t("oauth.revoke.flash", :application => @token.client_application.name)
index ceaf7e4c0d306f15d6f06ac17f9d94e027eb6087..282f6161325557326e65c2136d8a345e3db30fcb 100644 (file)
@@ -161,10 +161,10 @@ class SwfController < ApplicationController
   def swf_record(id, r)
     if r.length > 62
       # Long header: tag id, 0x3F, length
-      return pack_u16((id << 6) + 0x3F) + pack_u32(r.length) + r
+      pack_u16((id << 6) + 0x3F) + pack_u32(r.length) + r
     else
       # Short header: tag id, length
-      return pack_u16((id << 6) + r.length) + r
+      pack_u16((id << 6) + r.length) + r
     end
   end
 
@@ -195,7 +195,7 @@ class SwfController < ApplicationController
   # Find number of bits required to store arbitrary-length binary
 
   def length_sb(n)
-    Math.frexp(n + (n == 0 ? 1 : 0))[1] + 1
+    Math.frexp(n + (n.zero? ? 1 : 0))[1] + 1
   end
 
   # ====================================================================
index 60b5a4585330309f5c7aa1bf873ae6e5fe220dea..b7c9ccd70061357f324af38446c84b53b89afa65 100644 (file)
@@ -95,11 +95,11 @@ class TraceController < ApplicationController
       @title = t "trace.view.title", :name => @trace.name
     else
       flash[:error] = t "trace.view.trace_not_found"
-      redirect_to :controller => "trace", :action => "list"
+      redirect_to :action => "list"
     end
   rescue ActiveRecord::RecordNotFound
     flash[:error] = t "trace.view.trace_not_found"
-    redirect_to :controller => "trace", :action => "list"
+    redirect_to :action => "list"
   end
 
   def create
index e5515f727885e3464bb8372e8e7ce41f2b3a8f72..197b2891404c599046311e3a8ff5e48fd6c77023 100644 (file)
@@ -131,6 +131,10 @@ class UserController < ApplicationController
         session[:new_user_settings] = params
         redirect_to auth_url(params[:user][:auth_provider], params[:user][:auth_uid])
       end
+    elsif errors = session.delete(:user_errors)
+      errors.each do |attribute, error|
+        @user.errors.add(attribute, error)
+      end
     end
   end
 
@@ -138,14 +142,14 @@ class UserController < ApplicationController
     @user.data_public = true
     @user.save
     flash[:notice] = t "user.go_public.flash success"
-    redirect_to :controller => "user", :action => "account", :display_name => @user.display_name
+    redirect_to :action => "account", :display_name => @user.display_name
   end
 
   def lost_password
     @title = t "user.lost_password.title"
 
     if params[:user] && params[:user][:email]
-      user = User.visible.find_by_email(params[:user][:email])
+      user = User.visible.find_by(:email => params[:user][:email])
 
       if user.nil?
         users = User.visible.where("LOWER(email) = LOWER(?)", params[:user][:email])
@@ -168,7 +172,7 @@ class UserController < ApplicationController
     @title = t "user.reset_password.title"
 
     if params[:token]
-      token = UserToken.find_by_token(params[:token])
+      token = UserToken.find_by(:token => params[:token])
 
       if token
         @user = token.user
@@ -266,7 +270,7 @@ class UserController < ApplicationController
 
     if params[:session] == request.session_options[:id]
       if session[:token]
-        token = UserToken.find_by_token(session[:token])
+        token = UserToken.find_by(:token => session[:token])
         token.destroy if token
         session.delete(:token)
       end
@@ -282,7 +286,7 @@ class UserController < ApplicationController
 
   def confirm
     if request.post?
-      token = UserToken.find_by_token(params[:confirm_string])
+      token = UserToken.find_by(:token => params[:confirm_string])
       if token && token.user.active?
         flash[:error] = t("user.confirm.already active")
         redirect_to :action => "login"
@@ -293,12 +297,13 @@ class UserController < ApplicationController
         user = token.user
         user.status = "active"
         user.email_valid = true
+        flash[:notice] = gravatar_status_message(user) if gravatar_enable(user)
         user.save!
         referer = token.referer
         token.destroy
 
         if session[:token]
-          token = UserToken.find_by_token(session[:token])
+          token = UserToken.find_by(:token => session[:token])
           session.delete(:token)
         else
           token = nil
@@ -316,15 +321,15 @@ class UserController < ApplicationController
         end
       end
     else
-      user = User.find_by_display_name(params[:display_name])
+      user = User.find_by(:display_name => params[:display_name])
 
       redirect_to root_path if user.nil? || user.active?
     end
   end
 
   def confirm_resend
-    user = User.find_by_display_name(params[:display_name])
-    token = UserToken.find_by_token(session[:token])
+    user = User.find_by(:display_name => params[:display_name])
+    token = UserToken.find_by(:token => session[:token])
 
     if user.nil? || token.nil? || token.user != user
       flash[:error] = t "user.confirm_resend.failure", :name => params[:display_name]
@@ -338,14 +343,19 @@ class UserController < ApplicationController
 
   def confirm_email
     if request.post?
-      token = UserToken.find_by_token(params[:confirm_string])
+      token = UserToken.find_by(:token => params[:confirm_string])
       if token && token.user.new_email?
         @user = token.user
         @user.email = @user.new_email
         @user.new_email = nil
         @user.email_valid = true
+        gravatar_enabled = gravatar_enable(@user)
         if @user.save
-          flash[:notice] = t "user.confirm_email.success"
+          flash[:notice] = if gravatar_enabled
+                             t("user.confirm_email.success") + " " + gravatar_status_message(@user)
+                           else
+                             t("user.confirm_email.success")
+                           end
         else
           flash[:errors] = @user.errors
         end
@@ -383,7 +393,7 @@ class UserController < ApplicationController
   end
 
   def view
-    @this_user = User.find_by_display_name(params[:display_name])
+    @this_user = User.find_by(:display_name => params[:display_name])
 
     if @this_user &&
        (@this_user.visible? || (@user && @user.administrator?))
@@ -394,7 +404,7 @@ class UserController < ApplicationController
   end
 
   def make_friend
-    @new_friend = User.find_by_display_name(params[:display_name])
+    @new_friend = User.find_by(:display_name => params[:display_name])
 
     if @new_friend
       if request.post?
@@ -413,7 +423,7 @@ class UserController < ApplicationController
         if params[:referer]
           redirect_to params[:referer]
         else
-          redirect_to :controller => "user", :action => "view"
+          redirect_to :action => "view"
         end
       end
     else
@@ -422,7 +432,7 @@ class UserController < ApplicationController
   end
 
   def remove_friend
-    @friend = User.find_by_display_name(params[:display_name])
+    @friend = User.find_by(:display_name => params[:display_name])
 
     if @friend
       if request.post?
@@ -436,7 +446,7 @@ class UserController < ApplicationController
         if params[:referer]
           redirect_to params[:referer]
         else
-          redirect_to :controller => "user", :action => "view"
+          redirect_to :action => "view"
         end
       end
     else
@@ -449,14 +459,14 @@ class UserController < ApplicationController
   def set_status
     @this_user.status = params[:status]
     @this_user.save
-    redirect_to :controller => "user", :action => "view", :display_name => params[:display_name]
+    redirect_to :action => "view", :display_name => params[:display_name]
   end
 
   ##
   # delete a user, marking them as deleted and removing personal data
   def delete
     @this_user.delete
-    redirect_to :controller => "user", :action => "view", :display_name => params[:display_name]
+    redirect_to :action => "view", :display_name => params[:display_name]
   end
 
   ##
@@ -501,31 +511,14 @@ class UserController < ApplicationController
       email_verified = false
     end
 
-    user = User.find_by_auth_provider_and_auth_uid(provider, uid)
-
-    if user.nil? && provider == "google"
-      openid_url = auth_info[:extra][:id_info]["openid_id"]
-      user = User.find_by_auth_provider_and_auth_uid("openid", openid_url) if openid_url
-      user.update(:auth_provider => provider, :auth_uid => uid) if user
-    end
-
-    if user
-      case user.status
-      when "pending" then
-        unconfirmed_login(user)
-      when "active", "confirmed" then
-        successful_login(user, env["omniauth.params"]["referer"])
-      when "suspended" then
-        failed_login t("user.login.account is suspended", :webmaster => "mailto:#{SUPPORT_EMAIL}")
-      else
-        failed_login t("user.login.auth failure")
-      end
-    elsif settings = session.delete(:new_user_settings)
+    if settings = session.delete(:new_user_settings)
       @user.auth_provider = provider
       @user.auth_uid = uid
 
       update_user(@user, settings)
 
+      session[:user_errors] = @user.errors.as_json
+
       redirect_to :action => "account", :display_name => @user.display_name
     elsif session[:new_user]
       session[:new_user].auth_provider = provider
@@ -537,8 +530,29 @@ class UserController < ApplicationController
 
       redirect_to :action => "terms"
     else
-      redirect_to :action => "new", :nickname => name, :email => email,
-                  :auth_provider => provider, :auth_uid => uid
+      user = User.find_by(:auth_provider => provider, :auth_uid => uid)
+
+      if user.nil? && provider == "google"
+        openid_url = auth_info[:extra][:id_info]["openid_id"]
+        user = User.find_by(:auth_provider => "openid", :auth_uid => openid_url) if openid_url
+        user.update(:auth_provider => provider, :auth_uid => uid) if user
+      end
+
+      if user
+        case user.status
+        when "pending" then
+          unconfirmed_login(user)
+        when "active", "confirmed" then
+          successful_login(user, env["omniauth.params"]["referer"])
+        when "suspended" then
+          failed_login t("user.login.account is suspended", :webmaster => "mailto:#{SUPPORT_EMAIL}")
+        else
+          failed_login t("user.login.auth failure")
+        end
+      else
+        redirect_to :action => "new", :nickname => name, :email => email,
+                    :auth_provider => provider, :auth_uid => uid
+      end
     end
   end
 
@@ -587,15 +601,15 @@ class UserController < ApplicationController
   # try and come up with the correct URL based on what the user entered
   def openid_expand_url(openid_url)
     if openid_url.nil?
-      return nil
+      nil
     elsif openid_url.match(%r{(.*)gmail.com(/?)$}) || openid_url.match(%r{(.*)googlemail.com(/?)$})
       # Special case gmail.com as it is potentially a popular OpenID
       # provider and, unlike yahoo.com, where it works automatically, Google
       # have hidden their OpenID endpoint somewhere obscure this making it
       # somewhat less user friendly.
-      return "https://www.google.com/accounts/o8/id"
+      "https://www.google.com/accounts/o8/id"
     else
-      return openid_url
+      openid_url
     end
   end
 
@@ -614,7 +628,7 @@ class UserController < ApplicationController
     # - If they were referred to the login, send them back there.
     # - Otherwise, send them to the home page.
     if REQUIRE_TERMS_SEEN && !user.terms_seen
-      redirect_to :controller => :user, :action => :terms, :referer => target
+      redirect_to :action => :terms, :referer => target
     elsif user.blocked_on_view
       redirect_to user.blocked_on_view, :referer => target
     else
@@ -726,12 +740,12 @@ class UserController < ApplicationController
       flash[:error] = t("user.filter.not_an_administrator")
 
       if params[:display_name]
-        redirect_to :controller => "user", :action => "view", :display_name => params[:display_name]
+        redirect_to :action => "view", :display_name => params[:display_name]
       else
-        redirect_to :controller => "user", :action => "login", :referer => request.fullpath
+        redirect_to :action => "login", :referer => request.fullpath
       end
     elsif !@user
-      redirect_to :controller => "user", :action => "login", :referer => request.fullpath
+      redirect_to :action => "login", :referer => request.fullpath
     end
   end
 
@@ -752,9 +766,9 @@ class UserController < ApplicationController
   ##
   # ensure that there is a "this_user" instance variable
   def lookup_user_by_name
-    @this_user = User.find_by_display_name(params[:display_name])
+    @this_user = User.find_by(:display_name => params[:display_name])
   rescue ActiveRecord::RecordNotFound
-    redirect_to :controller => "user", :action => "view", :display_name => params[:display_name] unless @this_user
+    redirect_to :action => "view", :display_name => params[:display_name] unless @this_user
   end
 
   ##
@@ -791,4 +805,27 @@ class UserController < ApplicationController
 
     !blocked
   end
+
+  ##
+  # check if this user has a gravatar and set the user pref is true
+  def gravatar_enable(user)
+    # code from example https://en.gravatar.com/site/implement/images/ruby/
+    return false if user.image.present?
+    hash = Digest::MD5.hexdigest(user.email.downcase)
+    url = "https://www.gravatar.com/avatar/#{hash}?d=404" # without d=404 we will always get an image back
+    response = OSM.http_client.get(URI.parse(url))
+    oldsetting = user.image_use_gravatar
+    user.image_use_gravatar = response.success?
+    oldsetting != user.image_use_gravatar
+  end
+
+  ##
+  # display a message about th current status of the gravatar setting
+  def gravatar_status_message(user)
+    if user.image_use_gravatar
+      t "user.account.gravatar.enabled"
+    else
+      t "user.account.gravatar.disabled"
+    end
+  end
 end
index 78ab45308e874a9d7e56cad7efab1c6d63ca32c4..bf9bab213296f1ad4bc3324b480ad89f9a4895cd 100644 (file)
@@ -39,7 +39,7 @@ class UserPreferenceController < ApplicationController
 
     new_preferences = {}
 
-    doc = XML::Parser.string(request.raw_post).parse
+    doc = XML::Parser.string(request.raw_post, :options => XML::Parser::Options::NOERROR).parse
 
     doc.find("//preferences/preference").each do |pt|
       if preference = old_preferences.delete(pt["k"])
diff --git a/app/helpers/banner_helper.rb b/app/helpers/banner_helper.rb
new file mode 100644 (file)
index 0000000..4e88817
--- /dev/null
@@ -0,0 +1,53 @@
+module BannerHelper
+  def active_banners
+    BANNERS.reject do |_k, v|
+      enddate = v[:enddate]
+      begin
+        parsed = enddate && Date.parse(enddate)
+      rescue
+        parsed = nil
+      end
+      !parsed.is_a?(Date) || (parsed.is_a?(Date) && parsed.past?)
+    end
+  end
+
+  # returns the least recently seen banner that is not hidden
+  def next_banner
+    banners = active_banners
+    banner_key = nil
+    cookie_key = nil
+    min_index = 9999
+    min_date = Date.new(9999, 1, 1)
+
+    banners.each do |k, v|
+      ckey = banner_cookie(v[:id]).to_sym
+      cval = cookies[ckey] || 0
+      next if cval == "hide"
+
+      # rotate all banner queue positions
+      index = cval.to_i
+      cookies[ckey] = index - 1 if index > 0
+
+      # pick banner with mininum queue position
+      next if index > min_index
+
+      # or if equal queue position, pick banner with soonest end date (i.e. next expiring)
+      end_date = Date.parse(v[:enddate])
+      next if index == min_index && end_date > min_date
+
+      banner_key = k
+      cookie_key = ckey
+      min_index = index
+      min_date = end_date
+    end
+
+    unless banner_key.nil?
+      cookies[cookie_key] = banners.length # bump to end of queue
+      banners[banner_key]
+    end
+  end
+
+  def banner_cookie(key)
+    "_osm_banner_#{key}"
+  end
+end
index 494232744e3447feb079e31dd256db66fdf81413..ef7b3f554b8ffbb8dafb4eeb25799c6613a2ced1 100644 (file)
@@ -69,8 +69,13 @@ module BrowseHelper
   def format_value(key, value)
     if wp = wikipedia_link(key, value)
       link_to h(wp[:title]), wp[:url], :title => t("browse.tag_details.wikipedia_link", :page => wp[:title])
-    elsif wdt = wikidata_link(key, value)
-      link_to h(wdt[:title]), wdt[:url], :title => t("browse.tag_details.wikidata_link", :page => wdt[:title])
+    elsif wdt = wikidata_links(key, value)
+      # IMPORTANT: Note that wikidata_links() returns an array of hashes, unlike for example wikipedia_link(),
+      # which just returns one such hash.
+      wdt = wdt.map do |w|
+        link_to(w[:title], w[:url], :title => t("browse.tag_details.wikidata_link", :page => w[:title].strip))
+      end
+      safe_join(wdt, ";")
     elsif url = wiki_link("tag", "#{key}=#{value}")
       link_to h(value), url, :title => t("browse.tag_details.wiki_link.tag", :key => key, :value => value)
     elsif url = telephone_link(key, value)
@@ -128,14 +133,14 @@ module BrowseHelper
       lang = if value =~ /^([a-z-]{2,12}):(.+)$/i
                # Value is <lang>:<title> so split it up
                # Note that value is always left as-is, see: https://trac.openstreetmap.org/ticket/4315
-               $1
+               Regexp.last_match(1)
              else
                # Value is <title> so default to English Wikipedia
                "en"
              end
     elsif key =~ /^wikipedia:(\S+)$/
       # Language is in the key, so assume value is the title
-      lang = $1
+      lang = Regexp.last_match(1)
     else
       # Not a wikipedia key!
       return nil
@@ -144,9 +149,9 @@ module BrowseHelper
     if value =~ /^([^#]*)#(.*)/
       # Contains a reference to a section of the wikipedia article
       # Must break it up to correctly build the url
-      value = $1
-      section = "#" + $2
-      encoded_section = "#" + URI.encode($2.gsub(/ +/, "_"), /[^A-Za-z0-9:_]/).tr("%", ".")
+      value = Regexp.last_match(1)
+      section = "#" + Regexp.last_match(2)
+      encoded_section = "#" + URI.encode(Regexp.last_match(2).gsub(/ +/, "_"), /[^A-Za-z0-9:_]/).tr("%", ".")
     else
       section = ""
       encoded_section = ""
@@ -158,12 +163,21 @@ module BrowseHelper
     }
   end
 
-  def wikidata_link(key, value)
+  def wikidata_links(key, value)
+    # The simple wikidata-tag (this is limited to only one value)
     if key == "wikidata" && value =~ /^[Qq][1-9][0-9]*$/
-      return {
+      return [{
         :url => "//www.wikidata.org/wiki/#{value}?uselang=#{I18n.locale}",
         :title => value
-      }
+      }]
+    # Key has to be one of the accepted wikidata-tags
+    elsif key =~ /(architect|artist|brand|operator|subject):wikidata/ &&
+          # Value has to be a semicolon-separated list of wikidata-IDs (whitespaces allowed before and after semicolons)
+          value =~ /^[Qq][1-9][0-9]*(\s*;\s*[Qq][1-9][0-9]*)*$/
+      # Splitting at every semicolon to get a separate hash for each wikidata-ID
+      return value.split(";").map do |id|
+        { :title => id, :url => "//www.wikidata.org/wiki/#{id.strip}?uselang=#{I18n.locale}" }
+      end
     end
     nil
   end
index 2a101612928db938e68d3ccb51ce946cc467776a..6ebd18345526e186833527454e72895065c36539 100644 (file)
@@ -3,14 +3,12 @@ module NoteHelper
     if by.nil?
       I18n.t("browse.note." + event + "_by_anonymous",
              :when => friendly_date(at),
-             :exact_time => l(at)
-            ).html_safe
+             :exact_time => l(at)).html_safe
     else
       I18n.t("browse.note." + event + "_by",
              :when => friendly_date(at),
              :exact_time => l(at),
-             :user => note_author(by)
-            ).html_safe
+             :user => note_author(by)).html_safe
     end
   end
 
index 3922ce2b335e483af82af455710a7f445f0935b1..15bc3231316bb5340252be3d36fb35cfa016dff3 100644 (file)
@@ -1,9 +1,9 @@
 module TraceHelper
   def link_to_tag(tag)
     if @action == "mine"
-      return link_to(tag, :tag => tag, :page => nil)
+      link_to(tag, :tag => tag, :page => nil)
     else
-      return link_to(tag, :tag => tag, :display_name => @display_name, :page => nil)
+      link_to(tag, :tag => tag, :display_name => @display_name, :page => nil)
     end
   end
 end
index 8bb4ae4b9dd8ebf294419aa141ebeaea5f4d7994..529ccbe3bc26640dfb057674aca5b433ec1582d3 100644 (file)
@@ -1,4 +1,6 @@
 class Acl < ActiveRecord::Base
+  validates :k, :presence => true
+
   def self.match(address, domain = nil)
     if domain
       Acl.where("address >>= ? OR domain = ?", address, domain)
index 156eeafc7989cc15a6d03d504bef6477aa0604e8..152b3912dd24a2c37978d86be1a4e7a532d13b3c 100644 (file)
@@ -18,7 +18,7 @@ class ClientApplication < ActiveRecord::Base
   attr_accessor :token_callback_url
 
   def self.find_token(token_key)
-    token = OauthToken.find_by_token(token_key, :include => :client_application)
+    token = OauthToken.includes(:client_application).find_by(:token => token_key)
     token if token && token.authorized?
   end
 
index 368ee3aca802dc1770b7a5b87d25d38706205dea..e756432fdf4a3b285ec410dfddceb06f50d78442 100644 (file)
@@ -4,6 +4,8 @@ class DiaryEntry < ActiveRecord::Base
 
   has_many :comments, -> { order(:id).preload(:user) }, :class_name => "DiaryComment"
   has_many :visible_comments, -> { joins(:user).where(:visible => true, :users => { :status => %w(active confirmed) }).order(:id) }, :class_name => "DiaryComment"
+  has_many :subscriptions, :class_name => "DiaryEntrySubscription"
+  has_many :subscribers, :through => :subscriptions, :source => :user
 
   scope :visible, -> { where(:visible => true) }
 
diff --git a/app/models/diary_entry_subscription.rb b/app/models/diary_entry_subscription.rb
new file mode 100644 (file)
index 0000000..b0a563e
--- /dev/null
@@ -0,0 +1,4 @@
+class DiaryEntrySubscription < ActiveRecord::Base
+  belongs_to :user
+  belongs_to :diary_entry
+end
index a6814405c731195442304ee1f08d90107061d2cc..2a64259c10c0832d16c4ec8e2008aa7e34985947 100644 (file)
@@ -49,7 +49,7 @@ class Node < ActiveRecord::Base
 
   # Read in xml as text and return it's Node object representation
   def self.from_xml(xml, create = false)
-    p = XML::Parser.string(xml)
+    p = XML::Parser.string(xml, :options => XML::Parser::Options::NOERROR)
     doc = p.parse
 
     doc.find("//osm/node").each do |pt|
@@ -81,7 +81,7 @@ class Node < ActiveRecord::Base
       node.id = pt["id"].to_i
       # .to_i will return 0 if there is no number that can be parsed.
       # We want to make sure that there is no id with zero anyway
-      raise OSM::APIBadUserInput.new("ID of node cannot be zero when updating.") if node.id == 0
+      raise OSM::APIBadUserInput.new("ID of node cannot be zero when updating.") if node.id.zero?
     end
 
     # We don't care about the time, as it is explicitly set on create/update/delete
@@ -120,10 +120,10 @@ class Node < ActiveRecord::Base
       lock!
       check_consistency(self, new_node, user)
       ways = Way.joins(:way_nodes).where(:visible => true, :current_way_nodes => { :node_id => id }).order(:id)
-      raise OSM::APIPreconditionFailedError.new("Node #{id} is still used by ways #{ways.collect(&:id).join(",")}.") unless ways.empty?
+      raise OSM::APIPreconditionFailedError.new("Node #{id} is still used by ways #{ways.collect(&:id).join(',')}.") unless ways.empty?
 
       rels = Relation.joins(:relation_members).where(:visible => true, :current_relation_members => { :member_type => "Node", :member_id => id }).order(:id)
-      raise OSM::APIPreconditionFailedError.new("Node #{id} is still used by relations #{rels.collect(&:id).join(",")}.") unless rels.empty?
+      raise OSM::APIPreconditionFailedError.new("Node #{id} is still used by relations #{rels.collect(&:id).join(',')}.") unless rels.empty?
 
       self.changeset_id = new_node.changeset_id
       self.tags = {}
index 23f7b990781049948036d08842bcec877b0250ad..a498e4edf6cd88cb45c8e0be9bc8bb4f5d3bff2d 100644 (file)
@@ -83,9 +83,9 @@ class Notifier < ActionMailer::Base
     end
   end
 
-  def diary_comment_notification(comment)
-    with_recipient_locale comment.diary_entry.user do
-      @to_user = comment.diary_entry.user.display_name
+  def diary_comment_notification(comment, recipient)
+    with_recipient_locale recipient do
+      @to_user = recipient.display_name
       @from_user = comment.user.display_name
       @text = comment.body
       @title = comment.diary_entry.title
@@ -108,7 +108,7 @@ class Notifier < ActionMailer::Base
                           :title => "Re: #{comment.diary_entry.title}")
 
       mail :from => from_address(comment.user.display_name, "c", comment.id, comment.digest),
-           :to => comment.diary_entry.user.email,
+           :to => recipient.email,
            :subject => I18n.t("notifier.diary_comment_notification.subject", :user => comment.user.display_name)
     end
   end
index 062f0ed04ec073a869ecabfd3f5414e95e940c6d..ed37d159af3422437bdda4d00ce0319b381a3417 100644 (file)
@@ -36,7 +36,7 @@ class Relation < ActiveRecord::Base
   TYPES = %w(node way relation).freeze
 
   def self.from_xml(xml, create = false)
-    p = XML::Parser.string(xml)
+    p = XML::Parser.string(xml, :options => XML::Parser::Options::NOERROR)
     doc = p.parse
 
     doc.find("//osm/relation").each do |pt|
@@ -60,7 +60,7 @@ class Relation < ActiveRecord::Base
       relation.id = pt["id"].to_i
       # .to_i will return 0 if there is no number that can be parsed.
       # We want to make sure that there is no id with zero anyway
-      raise OSM::APIBadUserInput.new("ID of relation cannot be zero when updating.") if relation.id == 0
+      raise OSM::APIBadUserInput.new("ID of relation cannot be zero when updating.") if relation.id.zero?
     end
 
     # We don't care about the timestamp nor the visibility as these are either
index a1e98467648507fef371d1c827a03a67526696ca..47e5c38b7ee79be23de54384a73b11d0bf881006 100644 (file)
@@ -174,7 +174,7 @@ class Trace < ActiveRecord::Base
 
   # Read in xml as text and return it's Node object representation
   def self.from_xml(xml, create = false)
-    p = XML::Parser.string(xml)
+    p = XML::Parser.string(xml, :options => XML::Parser::Options::NOERROR)
     doc = p.parse
 
     doc.find("//osm/gpx_file").each do |pt|
@@ -197,7 +197,7 @@ class Trace < ActiveRecord::Base
       trace.id = pt["id"].to_i
       # .to_i will return 0 if there is no number that can be parsed.
       # We want to make sure that there is no id with zero anyway
-      raise OSM::APIBadUserInput.new("ID of trace cannot be zero when updating.") if trace.id == 0
+      raise OSM::APIBadUserInput.new("ID of trace cannot be zero when updating.") if trace.id.zero?
     end
 
     # We don't care about the time, as it is explicitly set on create/update/delete
index e255dc2169b1158cb735f4a3afc244223449409a..2cdb9404663ae26902506a6a59ab9e4e9ec0f242 100644 (file)
@@ -4,6 +4,8 @@ class User < ActiveRecord::Base
   has_many :traces, -> { where(:visible => true) }
   has_many :diary_entries, -> { order(:created_at => :desc) }
   has_many :diary_comments, -> { order(:created_at => :desc) }
+  has_many :diary_entry_subscriptions, :class_name => "DiaryEntrySubscription"
+  has_many :diary_subscriptions, :through => :diary_entry_subscriptions, :source => :diary_entry
   has_many :messages, -> { where(:to_user_visible => true).order(:sent_on => :desc).preload(:sender, :recipient) }, :foreign_key => :to_user_id
   has_many :new_messages, -> { where(:to_user_visible => true, :message_read => false).order(:sent_on => :desc) }, :class_name => "Message", :foreign_key => :to_user_id
   has_many :sent_messages, -> { where(:from_user_visible => true).order(:sent_on => :desc).preload(:sender, :recipient) }, :class_name => "Message", :foreign_key => :from_user_id
@@ -52,6 +54,8 @@ class User < ActiveRecord::Base
   validates :home_zoom, :allow_nil => true, :numericality => { :only_integer => true }
   validates :preferred_editor, :inclusion => Editors::ALL_EDITORS, :allow_nil => true
   validates :image, :attachment_content_type => { :content_type => %r{\Aimage/.*\Z} }
+  validates :auth_uid, :unless => proc { |u| u.auth_provider.nil? },
+                       :uniqueness => { :scope => :auth_provider }
 
   validates_email_format_of :email, :if => proc { |u| u.email_changed? }
   validates_email_format_of :new_email, :allow_blank => true, :if => proc { |u| u.new_email_changed? }
@@ -79,7 +83,7 @@ class User < ActiveRecord::Base
         user = nil
       end
     elsif options[:token]
-      token = UserToken.find_by_token(options[:token])
+      token = UserToken.find_by(:token => options[:token])
       user = token.user if token
     end
 
@@ -236,7 +240,7 @@ class User < ActiveRecord::Base
   ##
   # return an oauth access token for a specified application
   def access_token(application_key)
-    ClientApplication.find_by_key(application_key).access_token_for_user(self)
+    ClientApplication.find_by(:key => application_key).access_token_for_user(self)
   end
 
   private
index d0a252803631c7d1d81f391683cf8747d2718aba..98c4902f9e693cd2396aaf84761df00c0c3a8d83 100644 (file)
@@ -34,7 +34,7 @@ class Way < ActiveRecord::Base
 
   # Read in xml as text and return it's Way object representation
   def self.from_xml(xml, create = false)
-    p = XML::Parser.string(xml)
+    p = XML::Parser.string(xml, :options => XML::Parser::Options::NOERROR)
     doc = p.parse
 
     doc.find("//osm/way").each do |pt|
@@ -58,7 +58,7 @@ class Way < ActiveRecord::Base
       way.id = pt["id"].to_i
       # .to_i will return 0 if there is no number that can be parsed.
       # We want to make sure that there is no id with zero anyway
-      raise OSM::APIBadUserInput.new("ID of way cannot be zero when updating.") if way.id == 0
+      raise OSM::APIBadUserInput.new("ID of way cannot be zero when updating.") if way.id.zero?
     end
 
     # We don't care about the timestamp nor the visibility as these are either
@@ -222,7 +222,7 @@ class Way < ActiveRecord::Base
       lock!
       check_consistency(self, new_way, user)
       rels = Relation.joins(:relation_members).where(:visible => true, :current_relation_members => { :member_type => "Way", :member_id => id }).order(:id)
-      raise OSM::APIPreconditionFailedError.new("Way #{id} is still used by relations #{rels.collect(&:id).join(",")}.") unless rels.empty?
+      raise OSM::APIPreconditionFailedError.new("Way #{id} is still used by relations #{rels.collect(&:id).join(',')}.") unless rels.empty?
 
       self.changeset_id = new_way.changeset_id
       self.changeset = new_way.changeset
index 066f5678877965f76ba3915ec50d76867015d270..6d26a9e532521d05f826c3a38edb8a9d0462bb8e 100644 (file)
@@ -1,6 +1,6 @@
 # create list of permissions
-xml.instruct! :xml, :version=>"1.0"
-xml.osm("version" => "#{API_VERSION}", "generator" => "OpenStreetMap Server") do
+xml.instruct! :xml, :version => "1.0"
+xml.osm("version" => API_VERSION.to_s, "generator" => "OpenStreetMap Server") do
   xml.permissions do
     @permissions.each do |permission|
       xml.permission :name => permission
index 8ad5cbaa77f1fb4f206e7b16a00f263a573761c6..5c683c86d8ec224fe42ddd6d1bd5d5dc16e019ed 100644 (file)
@@ -1,17 +1,15 @@
 comments.each do |comment|
   xml.item do
     xml.title t("changeset.rss.comment", :author => comment.author.display_name, :changeset_id => comment.changeset.id.to_s)
-    
+
     xml.link url_for(:controller => "browse", :action => "changeset", :id => comment.changeset.id, :anchor => "c#{comment.id}", :only_path => false)
     xml.guid url_for(:controller => "browse", :action => "changeset", :id => comment.changeset.id, :anchor => "c#{comment.id}", :only_path => false)
 
     xml.description do
-      xml.cdata! render(:partial => "comment", :object => comment, :formats => [ :html ])
+      xml.cdata! render(:partial => "comment", :object => comment, :formats => [:html])
     end
 
-    if comment.author
-      xml.dc :creator, comment.author.display_name
-    end
+    xml.dc :creator, comment.author.display_name if comment.author
 
     xml.pubDate comment.created_at.to_s(:rfc822)
   end
index 60a229a30e73f97e86a437f104d71522f65e7ff0..f6d304a4cbd9bf8c6a4da50d1dba7341cbd23650 100644 (file)
@@ -1,14 +1,13 @@
-xml.rss("version" => "2.0", 
+xml.rss("version" => "2.0",
         "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
   xml.channel do
     if @changeset
-      xml.title t('changeset.rss.title_particular', :changeset_id => @changeset.id)
+      xml.title t("changeset.rss.title_particular", :changeset_id => @changeset.id)
     else
-      xml.title t('changeset.rss.title_all')
+      xml.title t("changeset.rss.title_all")
     end
     xml.link url_for(:controller => "site", :action => "index", :only_path => false)
 
     xml << render(:partial => "comments", :object => @comments)
   end
 end
-
index 3e0cd9ec58c6624bf3c27535f93cc5568351a607..979a7492f08efcc1cf4f82cb4690c167dc5d6446 100644 (file)
@@ -1,20 +1,20 @@
 atom_feed(:language => I18n.locale, :schema_date => 2009,
-          :id => url_for(params.merge({ :only_path => false })),
-          :root_url => url_for(params.merge({ :action => :list, :format => nil, :only_path => false })),
+          :id => url_for(params.merge(:only_path => false)),
+          :root_url => url_for(params.merge(:action => :list, :format => nil, :only_path => false)),
           "xmlns:georss" => "http://www.georss.org/georss") do |feed|
   feed.title changeset_list_title(params, @user)
 
-  feed.updated @edits.map {|e|  [e.created_at, e.closed_at].max }.max
+  feed.updated @edits.map { |e| [e.created_at, e.closed_at].max }.max
   feed.icon "http://#{SERVER_URL}/favicon.ico"
   feed.logo "http://#{SERVER_URL}/images/mag_map-rss2.0.png"
 
-  feed.rights :type => 'xhtml' do |xhtml|
+  feed.rights :type => "xhtml" do |xhtml|
     xhtml.a :href => "http://creativecommons.org/licenses/by-sa/2.0/" do |a|
       a.img :src => "http://#{SERVER_URL}/images/cc_button.png", :alt => "CC by-sa 2.0"
     end
   end
 
-  for changeset in @edits
+  @edits.each do |changeset|
     feed.entry(changeset, :updated => changeset.closed_at, :id => changeset_url(changeset.id, :only_path => false)) do |entry|
       entry.link :rel => "alternate",
                  :href => changeset_read_url(changeset, :only_path => false),
@@ -23,20 +23,20 @@ atom_feed(:language => I18n.locale, :schema_date => 2009,
                  :href => changeset_download_url(changeset, :only_path => false),
                  :type => "application/osmChange+xml"
 
-      if !changeset.tags.empty? and changeset.tags.has_key? "comment"
-        entry.title t('browse.changeset.feed.title_comment', :id => h(changeset.id), :comment => h(changeset.tags['comment'])), :type => "html"
+      if !changeset.tags.empty? && changeset.tags.key?("comment")
+        entry.title t("browse.changeset.feed.title_comment", :id => h(changeset.id), :comment => h(changeset.tags["comment"])), :type => "html"
       else
-        entry.title t('browse.changeset.feed.title', :id => h(changeset.id))
+        entry.title t("browse.changeset.feed.title", :id => h(changeset.id))
       end
 
       if changeset.user.data_public?
         entry.author do |author|
           author.name changeset.user.display_name
-          author.uri url_for(:controller => 'user', :action => 'view', :display_name => changeset.user.display_name, :only_path => false)
+          author.uri url_for(:controller => "user", :action => "view", :display_name => changeset.user.display_name, :only_path => false)
         end
       end
 
-      feed.content :type => 'xhtml' do |xhtml|
+      feed.content :type => "xhtml" do |xhtml|
         xhtml.style "th { text-align: left } tr { vertical-align: top }"
         xhtml.table do |table|
           table.tr do |tr|
index a4faeb34b1ed93f0ee164acfcd0bb14ece71f182..c878905e6ed17d63ac9c33713f53232949cc38a5 100644 (file)
@@ -1,12 +1,12 @@
 atom_feed(:language => I18n.locale, :schema_date => 2009,
-          :id => url_for(params.merge({ :only_path => false })),
-          :root_url => url_for(params.merge({ :only_path => false, :format => nil })),
+          :id => url_for(params.merge(:only_path => false)),
+          :root_url => url_for(params.merge(:only_path => false, :format => nil)),
           "xmlns:georss" => "http://www.georss.org/georss") do |feed|
   feed.title @title
 
-  feed.subtitle :type => 'xhtml' do |xhtml|
+  feed.subtitle :type => "xhtml" do |xhtml|
     xhtml.p do |p|
-      p << t('changeset.timeout.sorry')
+      p << t("changeset.timeout.sorry")
     end
   end
 end
index 240025fa7484a00ec0300ecf96c687a1ed0a86f2..7adcb3b5245309c17693cabaea040e3170d8f8d7 100644 (file)
@@ -1,6 +1,6 @@
 xml.instruct!
 
-xml.rss("version" => "2.0", 
+xml.rss("version" => "2.0",
         "xmlns:geo" => "http://www.w3.org/2003/01/geo/wgs84_pos#",
         "xmlns:georss" => "http://www.georss.org/georss") do
   xml.channel do
@@ -12,10 +12,10 @@ xml.rss("version" => "2.0",
       xml.title "OpenStreetMap"
       xml.width "100"
       xml.height "100"
-      xml.link url_for(:action => "list", :host=> SERVER_URL)
+      xml.link url_for(:action => "list", :host => SERVER_URL)
     end
 
-    for entry in @entries
+    @entries.each do |entry|
       xml.item do
         xml.title h(entry.title)
         xml.link url_for(:action => "view", :id => entry.id, :display_name => entry.user.display_name, :host => SERVER_URL)
@@ -24,11 +24,11 @@ xml.rss("version" => "2.0",
         xml.author entry.user.display_name
         xml.pubDate entry.created_at.to_s(:rfc822)
         xml.comments url_for(:action => "view", :id => entry.id, :display_name => entry.user.display_name, :anchor => "comments", :host => SERVER_URL)
-        
-        if entry.latitude and entry.longitude
+
+        if entry.latitude && entry.longitude
           xml.geo :lat, entry.latitude.to_s
           xml.geo :long, entry.longitude.to_s
-          xml.georss :point, "#{entry.latitude.to_s} #{entry.longitude.to_s}"
+          xml.georss :point, "#{entry.latitude} #{entry.longitude}"
         end
       end
     end
index d12942a7b9b9f98f8286afde37f359fc6dd5f774..6a2a21abcba3bf26b0b341a5dd1fb4019501af57 100644 (file)
     <%= richtext_area :diary_comment, :body, :cols => 80, :rows => 15 %>
     <%= submit_tag t('diary_entry.view.save_button') %>
   <% end %>
+  <% if @user and @entry.subscribers.exists?(@user.id) %>
+    <div class="diary-subscribe-buttons"><%= link_to t('javascripts.changesets.show.unsubscribe'), diary_entry_unsubscribe_path(:display_name => @entry.user.display_name, :id => @entry.id), :method => :post, :class => :button %></div>
+  <% elsif @user %>
+    <div class="diary-subscribe-buttons"><%= link_to t('javascripts.changesets.show.subscribe'), diary_entry_subscribe_path(:display_name => @entry.user.display_name, :id => @entry.id), :method => :post, :class => :button %></div>
+  <% end %>
 <% end %>
 
 <%= if_not_logged_in(:div) do %>
diff --git a/app/views/layouts/_banner.html.erb b/app/views/layouts/_banner.html.erb
new file mode 100644 (file)
index 0000000..bd0c902
--- /dev/null
@@ -0,0 +1,4 @@
+<% unless (banner = next_banner()).nil? %>
+<%= link_to (image_tag banner[:img], :alt => banner[:alt], :title => banner[:alt]), banner[:link] %>
+<div class="close-wrap" id="<%= banner_cookie(banner[:id]) %>"><span class="icon close"></span></div>
+<% end %>
index cb2fd0e07a33007e082d437710ee88b75effba5d..6607bf7a5879eba6d026edbe809fc42835947516 100644 (file)
 
     <% unless @user %>
       <div class="welcome">
-        <h2><a><span class="icon close"></span></a><%= t 'layouts.intro_header' %></h2>
+        <h2><%= t 'layouts.intro_header' %></h2>
+        <div class="close-wrap"><span class="icon close"></span></div>
         <p><%= t 'layouts.intro_text' %></p>
         <a class="button learn-more" href="<%= about_path %>"><%= t('layouts.learn_more') %></a>
         <a class="button sign-up" href="<%= user_new_path %>"><%= t('layouts.start_mapping') %></a>
       </div>
     <% end %>
+
+    <div id="banner">
+      <%= render :partial => "layouts/banner" %>
+    </div>
   </div>
 
   <noscript>
index 8a96db81cc61bdb3882f4e3ab089e8a13670f7d0..9d8ede249d80a711c74b39794700b5bbf30ab014 100644 (file)
@@ -3,7 +3,7 @@ xml.wpt("lon" => note.lon, "lat" => note.lat) do
   xml.name t("browse.note.title", :id => note.id)
 
   xml.desc do
-    xml.cdata! render(:partial => "description", :object => note, :formats => [ :html ])
+    xml.cdata! render(:partial => "description", :object => note, :formats => [:html])
   end
 
   xml.link("href" => browse_note_url(note, :host => SERVER_URL))
@@ -22,8 +22,6 @@ xml.wpt("lon" => note.lon, "lat" => note.lat) do
     xml.date_created note.created_at
     xml.status note.status
 
-    if note.closed?
-      xml.date_closed note.closed_at
-    end
+    xml.date_closed note.closed_at if note.closed?
   end
 end
index a095b636d9ed45a8bf907a7731f140597168e36f..900e7fd7cb328bfcb0e6e3b59ef2e8b4cafcc4b8 100644 (file)
@@ -2,20 +2,18 @@ xml.item do
   location = describe_location(note.lat, note.lon, 14, locale)
 
   if note.closed?
-    xml.title t('note.rss.closed', :place => location)
+    xml.title t("note.rss.closed", :place => location)
   elsif note.comments.length > 1
-    xml.title t('note.rss.commented', :place => location)
+    xml.title t("note.rss.commented", :place => location)
   else
-    xml.title t('note.rss.opened', :place => location)
+    xml.title t("note.rss.opened", :place => location)
   end
 
   xml.link browse_note_url(note)
   xml.guid note_url(note)
-  xml.description render(:partial => "description", :object => note, :formats => [ :html ])
+  xml.description render(:partial => "description", :object => note, :formats => [:html])
 
-  if note.author
-    xml.author note.author.display_name
-  end
+  xml.author note.author.display_name if note.author
 
   xml.pubDate note.updated_at.to_s(:rfc822)
   xml.geo :lat, note.lat
index ee9570205ce8e79d18e982aaea5487831cb51090..fb6738aaa1c6342a150f8c69670abe0b5987f3ca 100644 (file)
@@ -12,9 +12,7 @@ xml.note("lon" => note.lon, "lat" => note.lat) do
   xml.date_created note.created_at
   xml.status note.status
 
-  if note.closed?
-    xml.date_closed note.closed_at
-  end
+  xml.date_closed note.closed_at if note.closed?
 
   xml.comments do
     note.comments.each do |comment|
index e663d94a60ff8d19c61cfb0cb4ccc4ddc84829f9..708192e5f48f020149ead7ef6dadd3aabdb5ee1c 100644 (file)
@@ -1,12 +1,12 @@
 xml.instruct!
 
-xml.rss("version" => "2.0", 
+xml.rss("version" => "2.0",
         "xmlns:dc" => "http://purl.org/dc/elements/1.1/",
         "xmlns:geo" => "http://www.w3.org/2003/01/geo/wgs84_pos#",
         "xmlns:georss" => "http://www.georss.org/georss") do
   xml.channel do
-    xml.title t('note.rss.title')
-    xml.description t('note.rss.description_area', :min_lat => @min_lat, :min_lon => @min_lon, :max_lat => @max_lat, :max_lon => @max_lon )
+    xml.title t("note.rss.title")
+    xml.description t("note.rss.description_area", :min_lat => @min_lat, :min_lon => @min_lon, :max_lat => @max_lat, :max_lon => @max_lon)
     xml.link url_for(:controller => "site", :action => "index", :only_path => false)
 
     @comments.each do |comment|
@@ -14,17 +14,15 @@ xml.rss("version" => "2.0",
 
       xml.item do
         xml.title t("note.rss.#{comment.event}", :place => location)
-        
+
         xml.link url_for(:controller => "browse", :action => "note", :id => comment.note.id, :anchor => "c#{comment.id}", :only_path => false)
         xml.guid url_for(:controller => "browse", :action => "note", :id => comment.note.id, :anchor => "c#{comment.id}", :only_path => false)
 
         xml.description do
-          xml.cdata! render(:partial => "entry", :object => comment, :formats => [ :html ])
+          xml.cdata! render(:partial => "entry", :object => comment, :formats => [:html])
         end
 
-        if comment.author
-          xml.dc :creator, comment.author.display_name
-        end
+        xml.dc :creator, comment.author.display_name if comment.author
 
         xml.pubDate comment.created_at.to_s(:rfc822)
         xml.geo :lat, comment.note.lat
index 5207ec3f81d82430913b4a18ce9cdb0c08fcbf0c..58da357da5f6daa688ed27de65f333c2c83b9858 100644 (file)
@@ -1,6 +1,6 @@
 xml.instruct!
 
-xml.gpx("version" => "1.1", 
+xml.gpx("version" => "1.1",
         "creator" => "OpenStreetMap.org",
         "xmlns" => "http://www.topografix.com/GPX/1/1",
         "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
index 53806f50207960699523bab209f3d137ce0081b9..ecbbb73263afac0bc5c757b2101195692a9ac372 100644 (file)
@@ -1,11 +1,11 @@
 xml.instruct!
 
-xml.rss("version" => "2.0", 
+xml.rss("version" => "2.0",
         "xmlns:geo" => "http://www.w3.org/2003/01/geo/wgs84_pos#",
         "xmlns:georss" => "http://www.georss.org/georss") do
   xml.channel do
-    xml.title t('note.rss.title')
-    xml.description t('note.rss.description_area', :min_lat => @min_lat, :min_lon => @min_lon, :max_lat => @max_lat, :max_lon => @max_lon )
+    xml.title t("note.rss.title")
+    xml.description t("note.rss.description_area", :min_lat => @min_lat, :min_lon => @min_lon, :max_lat => @max_lat, :max_lon => @max_lon)
     xml.link url_for(:controller => "site", :action => "index", :only_path => false)
 
     xml << (render(:partial => "note", :collection => @notes) || "")
index 8bb6c9688c60cae7f62113c813d23b5d9b6b4b40..f87ff4dd947ba2f8f323287e6a9916cbe04644d0 100644 (file)
@@ -1,6 +1,6 @@
 xml.instruct!
 
-xml.gpx("version" => "1.1", 
+xml.gpx("version" => "1.1",
         "creator" => "OpenStreetMap.org",
         "xmlns" => "http://www.topografix.com/GPX/1/1",
         "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
index e566ff02ec2b224ff2e3222e9f410893259e618d..62ccbe8a94a4ab2f3f2969eff254b4264ae65d1f 100644 (file)
@@ -1,11 +1,11 @@
 xml.instruct!
 
-xml.rss("version" => "2.0", 
+xml.rss("version" => "2.0",
         "xmlns:geo" => "http://www.w3.org/2003/01/geo/wgs84_pos#",
         "xmlns:georss" => "http://www.georss.org/georss") do
   xml.channel do
-    xml.title t('note.rss.title')
-    xml.description t('note.rss.description_item', :id => @note.id)
+    xml.title t("note.rss.title")
+    xml.description t("note.rss.description_item", :id => @note.id)
     xml.link url_for(:controller => "site", :action => "index", :only_path => false)
 
     xml << render(:partial => "note", :object => @note)
index 0b2e26d11e66e49b9c52cef2f2982aebcb53134b..176f2bdbf9c9aa43f8197d4fb74d3283bce2478f 100644 (file)
@@ -1,6 +1,6 @@
 xml.instruct!
 
-xml.rss("version" => "2.0", 
+xml.rss("version" => "2.0",
         "xmlns:dc" => "http://purl.org/dc/elements/1.1/",
         "xmlns:geo" => "http://www.w3.org/2003/01/geo/wgs84_pos#",
         "xmlns:georss" => "http://www.georss.org/georss") do
@@ -25,14 +25,14 @@ xml.rss("version" => "2.0",
         xml.guid url_for(:controller => :trace, :action => :view, :id => trace.id, :display_name => trace.user.display_name, :only_path => false)
 
         xml.description do
-          xml.cdata! render(:partial => "description", :object => trace, :formats => [ :html ])
+          xml.cdata! render(:partial => "description", :object => trace, :formats => [:html])
         end
 
         xml.dc :creator, trace.user.display_name
 
         xml.pubDate trace.timestamp.to_s(:rfc822)
 
-        if trace.latitude and trace.longitude
+        if trace.latitude && trace.longitude
           xml.geo :lat, trace.latitude
           xml.geo :long, trace.longitude
           xml.georss :point, "#{trace.latitude} #{trace.longitude}"
index e976954206f08fe892c2405ecc492fdc7fdc22c8..7136b9f5867af6de53994dcad04ff5527a4f95d7 100644 (file)
@@ -3,16 +3,14 @@ xml.osm("version" => API_VERSION, "generator" => GENERATOR) do
   xml.tag! "user", :id => @this_user.id,
                    :display_name => @this_user.display_name,
                    :account_created => @this_user.creation_time.xmlschema do
-    if @this_user.description
-      xml.tag! "description", @this_user.description
-    end
+    xml.tag! "description", @this_user.description if @this_user.description
     if @user && @user == @this_user
-      xml.tag! "contributor-terms", :agreed => !!@this_user.terms_agreed,
-                                    :pd => !!@this_user.consider_pd
+      xml.tag! "contributor-terms", :agreed => @this_user.terms_agreed.present?,
+                                    :pd => @this_user.consider_pd
     else
-      xml.tag! "contributor-terms", :agreed => !!@this_user.terms_agreed
+      xml.tag! "contributor-terms", :agreed => @this_user.terms_agreed.present?
     end
-    if @this_user.image.file? or @this_user.image_use_gravatar
+    if @this_user.image.file? || @this_user.image_use_gravatar
       xml.tag! "img", :href => user_image_url(@this_user, :size => 256)
     end
     xml.tag! "roles" do
@@ -31,7 +29,7 @@ xml.osm("version" => API_VERSION, "generator" => GENERATOR) do
       end
     end
     if @user && @user == @this_user
-      if @this_user.home_lat and @this_user.home_lon
+      if @this_user.home_lat && @this_user.home_lon
         xml.tag! "home", :lat => @this_user.home_lat,
                          :lon => @this_user.home_lon,
                          :zoom => @this_user.home_zoom
index e6efdc5ce72460a2bd9421efea843fb6544b94a1..3d28a770aa303a3da94a8f1079a122146c282413 100644 (file)
@@ -55,6 +55,9 @@
           <% if defined?(WINDOWSLIVE_AUTH_ID) -%>
           <li><%= auth_button "windowslive", "windowslive" %></li>
           <% end -%>
+          <% if defined?(GITHUB_AUTH_ID) -%>
+          <li><%= auth_button "github", "github" %></li>
+          <% end -%>
           <li><%= auth_button "yahoo", "openid", :openid_url => "yahoo.com" %></li>
           <li><%= auth_button "wordpress", "openid", :openid_url => "wordpress.com" %></li>
           <li><%= auth_button "aol", "openid", :openid_url => "aol.com" %></li>
diff --git a/config/banners.yml b/config/banners.yml
new file mode 100644 (file)
index 0000000..3b151af
--- /dev/null
@@ -0,0 +1,20 @@
+sotmasia2016:
+  id: sotmasia2016
+  alt: State of the Map Asia 2016
+  link: http://stateofthemap.asia/
+  img: banners/sotmasia-2016.jpg
+  enddate: 2016-oct-01
+
+donate2016:
+  id: donate2016
+  alt: OpenStreetMap Funding Drive 2016
+  link: https://donate.openstreetmap.org/
+  img: banners/donate-2016.jpg
+  enddate: 2016-oct-31
+
+sotmlatam2016:
+  id: sotmlatam2016
+  alt: State of the Map Latam 2016
+  link: http://state.osmlatam.org/
+  img: banners/sotmlatam-2016.jpg
+  enddate: 2016-nov-25
index 5e2014ba96c3a86b0339ce6b5dfaa3bc33831105..b5d4db363f054d8b14af4eab88777850b2bf99d2 100644 (file)
@@ -87,16 +87,16 @@ defaults: &defaults
   require_terms_agreed: false
   # Imagery to return in capabilities as blacklisted
   imagery_blacklist:
-    - ".*\\.googleapis\\.com/.*"
-    - ".*\\.google\\.com/.*"
-    - ".*\\.google\\.ru/.*"
+    # Current Google imagery URLs have google or googleapis in the domain
+    # with a vt or kh endpoint, and x, y and z query parameters
+    - ".*\\.google(apis)?\\..*/(vt|kh)[\\?/].*([xyz]=.*){3}.*"
   # URL of Overpass instance to use for feature queries
   overpass_url: "//overpass-api.de/api/interpreter"
   # Routing endpoints
   graphhopper_url: "//graphhopper.com/api/1/route"
   mapquest_directions_url: "//open.mapquestapi.com/directions/v2/route"
   mapzen_valhalla_url: "//valhalla.mapzen.com/route"
-  osrm_url: "//router.project-osrm.org/viaroute"
+  osrm_url: "//router.project-osrm.org/route/v1/driving/"
   # External authentication credentials
   #google_auth_id: ""
   #google_auth_secret: ""
@@ -105,10 +105,14 @@ defaults: &defaults
   #facebook_auth_secret: ""
   #windowslive_auth_id: ""
   #windowslive_auth_secret: ""
+  #github_auth_id: ""
+  #github_auth_secret: ""
   # MapQuest authentication details
   #mapquest_key: ""
   # Mapzen authentication details
   #mapzen_valhalla_key: ""
+  # Thunderforest authentication details
+  #thunderforest_key: ""
 
 development:
   <<: *defaults
@@ -128,3 +132,5 @@ test:
   facebook_auth_secret: "dummy"
   windowslive_auth_id: "dummy"
   windowslive_auth_secret: "dummy"
+  github_auth_id: "dummy"
+  github_auth_secret: "dummy"
index f59f60820e7edce2072f1b097b35fa09dbba9512..da975acc9e90c1804060f615775a5d9d4724ceac 100644 (file)
@@ -11,24 +11,24 @@ Rails.application.config.assets.paths << Rails.root.join("config")
 
 # Precompile additional assets.
 # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
-Rails.application.config.assets.precompile += %w( index.js browse.js welcome.js fixthemap.js )
-Rails.application.config.assets.precompile += %w( user.js login.js diary_entry.js )
-Rails.application.config.assets.precompile += %w( screen-ltr.css print-ltr.css )
-Rails.application.config.assets.precompile += %w( screen-rtl.css print-rtl.css )
-Rails.application.config.assets.precompile += %w( leaflet-all.css leaflet.ie.css )
-Rails.application.config.assets.precompile += %w( id.js id.css )
-Rails.application.config.assets.precompile += %w( embed.js embed.css )
-Rails.application.config.assets.precompile += %w( html5shiv.js )
-Rails.application.config.assets.precompile += %w( images/marker-*.png img/*-handle.png )
-Rails.application.config.assets.precompile += %w( swfobject.js expressInstall.swf )
-Rails.application.config.assets.precompile += %w( potlatch2.swf )
-Rails.application.config.assets.precompile += %w( potlatch2/assets.zip )
-Rails.application.config.assets.precompile += %w( potlatch2/FontLibrary.swf )
-Rails.application.config.assets.precompile += %w( potlatch2/locales/*.swf )
-Rails.application.config.assets.precompile += %w( help/introduction.* )
-Rails.application.config.assets.precompile += %w( iD/img/*.svg iD/img/*.png iD/img/*.gif )
-Rails.application.config.assets.precompile += %w( iD/img/pattern/*.png )
-Rails.application.config.assets.precompile += %w( iD/locales/*.json )
-Rails.application.config.assets.precompile += %w( iD/traffico/stylesheets/traffico.css )
-Rails.application.config.assets.precompile += %w( iD/traffico/fonts/traffico_* )
-Rails.application.config.assets.precompile += %w( iD/traffico/string-maps/*.json )
+Rails.application.config.assets.precompile += %w(index.js browse.js welcome.js fixthemap.js)
+Rails.application.config.assets.precompile += %w(user.js login.js diary_entry.js)
+Rails.application.config.assets.precompile += %w(screen-ltr.css print-ltr.css)
+Rails.application.config.assets.precompile += %w(screen-rtl.css print-rtl.css)
+Rails.application.config.assets.precompile += %w(leaflet-all.css leaflet.ie.css)
+Rails.application.config.assets.precompile += %w(id.js id.css)
+Rails.application.config.assets.precompile += %w(embed.js embed.css)
+Rails.application.config.assets.precompile += %w(html5shiv.js)
+Rails.application.config.assets.precompile += %w(images/marker-*.png img/*-handle.png)
+Rails.application.config.assets.precompile += %w(swfobject.js expressInstall.swf)
+Rails.application.config.assets.precompile += %w(potlatch2.swf)
+Rails.application.config.assets.precompile += %w(potlatch2/assets.zip)
+Rails.application.config.assets.precompile += %w(potlatch2/FontLibrary.swf)
+Rails.application.config.assets.precompile += %w(potlatch2/locales/*.swf)
+Rails.application.config.assets.precompile += %w(help/introduction.*)
+Rails.application.config.assets.precompile += %w(iD/img/*.svg iD/img/*.png iD/img/*.gif)
+Rails.application.config.assets.precompile += %w(iD/img/pattern/*.png)
+Rails.application.config.assets.precompile += %w(iD/locales/*.json)
+Rails.application.config.assets.precompile += %w(iD/traffico/stylesheets/traffico.css)
+Rails.application.config.assets.precompile += %w(iD/traffico/fonts/traffico_*)
+Rails.application.config.assets.precompile += %w(iD/traffico/string-maps/*.json)
diff --git a/config/initializers/banners.rb b/config/initializers/banners.rb
new file mode 100644 (file)
index 0000000..cda96e0
--- /dev/null
@@ -0,0 +1,5 @@
+begin
+  BANNERS = YAML.load_file("#{Rails.root}/config/banners.yml").deep_symbolize_keys
+rescue
+  BANNERS = {}.freeze
+end
index 610053141205f03dbb9b5849dd254ddb86d23c9d..f7d0c5f6ac4b0d698a46ac13ea7dfd29942d5d1a 100644 (file)
@@ -23,6 +23,7 @@ openid_options = { :name => "openid", :store => openid_store }
 google_options = { :name => "google", :scope => "email", :access_type => "online" }
 facebook_options = { :name => "facebook", :scope => "email" }
 windowslive_options = { :name => "windowslive", :scope => "wl.signin,wl.emails" }
+github_options = { :name => "github", :scope => "user:email" }
 
 if defined?(GOOGLE_OPENID_REALM)
   google_options[:openid_realm] = GOOGLE_OPENID_REALM
@@ -33,6 +34,7 @@ Rails.application.config.middleware.use OmniAuth::Builder do
   provider :google_oauth2, GOOGLE_AUTH_ID, GOOGLE_AUTH_SECRET, google_options if defined?(GOOGLE_AUTH_ID)
   provider :facebook, FACEBOOK_AUTH_ID, FACEBOOK_AUTH_SECRET, facebook_options if defined?(FACEBOOK_AUTH_ID)
   provider :windowslive, WINDOWSLIVE_AUTH_ID, WINDOWSLIVE_AUTH_SECRET, windowslive_options if defined?(WINDOWSLIVE_AUTH_ID)
+  provider :github, GITHUB_AUTH_ID, GITHUB_AUTH_SECRET, github_options if defined?(GITHUB_AUTH_ID)
 end
 
 # Pending fix for: https://github.com/intridea/omniauth/pull/795
index e27c46ea70a406fd08425cec7be982de97021e88..4db3166ae9a4419003f541bc53772ddc557e9dc6 100644 (file)
@@ -6,7 +6,7 @@ module Paperclip
       url = super(style_name, options)
 
       if url =~ %r{^/assets/(.*)$}
-        asset_path($1)
+        asset_path(Regexp.last_match(1))
       else
         url
       end
index 545d7bc0274db58afb8488d731ad9ed45f8c6315..7fbb5c115002480f2f969303f7ca0b3fefbc9be5 100644 (file)
@@ -1,23 +1,16 @@
-class R2Template < Tilt::Template
-  self.default_mime_type = "text/css"
+require "r2"
 
-  def self.engine_initialized?
-    defined? ::R2
-  end
-
-  def initialize_engine
-    require_template_library "r2"
-  end
-
-  def prepare
-    @output = R2.r2(data)
-  end
-
-  def evaluate(_scope, _locals, &_block)
-    @output
+class R2ScssProcessor < Sprockets::ScssProcessor
+  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_engine ".r2", R2Template
+  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
index b6c9b50cf42b1933bb72b44c103e0b1abef5f049..4446fbe6ec84d87af801d8ccbff931010b70b85f 100644 (file)
@@ -44,3 +44,29 @@ mapnik:
   - { min_zoom: 15, max_zoom: 19, name: private, image: private.png }
   - { min_zoom: 15, max_zoom: 19, name: destination, image: destination.png }
   - { min_zoom: 12, max_zoom: 19, name: construction, image: construction.png }
+cyclemap:
+  - { min_zoom: 0, max_zoom: 11, name: motorway, image: motorway.png }
+  - { min_zoom: 12, max_zoom: 19, name: motorway, image: motorway12.png }
+  - { min_zoom: 0, max_zoom: 11, name: trunk, image: trunk.png }
+  - { min_zoom: 12, max_zoom: 19, name: trunk, image: trunk12.png }
+  - { min_zoom: 7, max_zoom: 11, name: primary, image: primary.png }
+  - { min_zoom: 12, max_zoom: 19, name: primary, image: primary12.png }
+  - { min_zoom: 9, max_zoom: 11, name: secondary, image: secondary.png }
+  - { min_zoom: 12, max_zoom: 19, name: secondary, image: secondary12.png }
+  - { min_zoom: 13, max_zoom: 19, name: track, image: track.png }
+  - { min_zoom: 8, max_zoom: 19, name: cycleway, image: cycleway.png }
+  - { min_zoom: 5, max_zoom: 12, name: cycleway_national, image: cycleway_national.png }
+  - { min_zoom: 13, max_zoom: 19, name: cycleway_national, image: cycleway_national13.png }
+  - { min_zoom: 5, max_zoom: 12, name: cycleway_regional, image: cycleway_regional.png }
+  - { min_zoom: 13, max_zoom: 19, name: cycleway_regional, image: cycleway_regional13.png }
+  - { min_zoom: 8, max_zoom: 12, name: cycleway_local, image: cycleway_local.png }
+  - { min_zoom: 13, max_zoom: 19, name: cycleway_local, image: cycleway_local13.png }
+  - { min_zoom: 13, max_zoom: 19, name: footway, image: footway.png }
+  - { min_zoom: 7, max_zoom: 13, name: rail, image: rail.png }
+  - { min_zoom: 14, max_zoom: 19, name: rail, image: rail14.png }
+  - { min_zoom: 9, max_zoom: 19, name: forest, image: forest.png }
+  - { min_zoom: 10, max_zoom: 19, name: common, image: common.png }
+  - { min_zoom: 7, max_zoom: 19, name: lake, image: lake.png }
+  - { min_zoom: 14, max_zoom: 19, name: bicycle_shop, image: bicycle_shop.png }
+  - { min_zoom: 14, max_zoom: 19, name: bicycle_parking, image: bicycle_parking.png }
+  - { min_zoom: 16, max_zoom: 19, name: toilets, image: toilets.png }
index eaacc98b9c8818e56775c5e434d375d2af58f383..e94d829b8f6dbd12ad5f5e9c0d5005b18c6428bc 100644 (file)
@@ -19,7 +19,9 @@
 # Author: TTMTT
 # Author: Yahya Sakhnini
 # Author: Zaher kadour
+# Author: بدارين
 # Author: ترجمان05
+# Author: ديفيد
 # Author: عباد ديرانية
 # Author: عبد الرحمان أيمن
 # Author: محمد أحمد عبد الفتاح
@@ -143,6 +145,7 @@ ar:
         مضت</abbr>
       commented_by: تعليق من %{user} <abbr title='%{exact_time}'>%{when} مضت</abbr>
       changesetxml: حزمة التغييرات إكس إم أل
+      osmchangexml: osmChange XML
       feed:
         title: حزمة التغييرات %{id}
         title_comment: حزمة التغييرات %{id} - %{comment}
@@ -399,6 +402,7 @@ ar:
     search_osm_nominatim:
       prefix:
         aerialway:
+          cable_car: عربة قطار هوائي
           station: محطة قطار هوائي
         aeroway:
           aerodrome: المطار
@@ -409,6 +413,7 @@ ar:
           taxiway: مدرج المناورات
           terminal: صالة مطار
         amenity:
+          animal_shelter: مأوى للحيوانات
           arts_centre: مركز فني/ثقافي
           atm: صراف آلي
           bank: مصرف
@@ -418,6 +423,7 @@ ar:
           bicycle_parking: موقف دراجات
           bicycle_rental: تأجير دراجة
           biergarten: حديقة البيرة
+          boat_rental: تأجير قوارب
           brothel: بيت دعارة
           bureau_de_change: مكتب صرافة
           bus_station: محطة حافلات
@@ -512,6 +518,7 @@ ar:
         building:
           "yes": مبنى
         craft:
+          brewery: مصنع الجعة
           carpenter: نجار
           electrician: اختصاصي كهرباء
           gardener: بستاني
@@ -702,7 +709,7 @@ ar:
           volcano: بركان
           water: ماء
           wetland: أرض رطبة
-          wood: Ø­Ø±Ø¬
+          wood: ØºØ§Ø¨Ø©
         office:
           accountant: محاسب
           administrative: إدارة
@@ -886,6 +893,7 @@ ar:
           wadi: وادي
           waterfall: شلال
           weir: هدار (سدّ منخفض)
+          "yes": معبر مائي
       admin_levels:
         level2: حدود قطرية
         level4: حدود الدولة
@@ -913,7 +921,7 @@ ar:
     logout: سجل خروج
     log_in: لِج
     log_in_tooltip: سجّل الدخول مع حساب موجود
-    sign_up: Ø¥Ù\86شئ Ø­Ø³Ø§Ø¨Ø§Ù\8b
+    sign_up: Ø£Ù\86شئ Ø­Ø³Ø§Ø¨Ù\8bا
     sign_up_tooltip: أنشئ حسابًا كي تستطيع المساهمة
     edit: تعديل
     history: تاريخ
@@ -960,13 +968,15 @@ ar:
     native:
       title: حول هذه الصفحة
       native_link: النسخة العربية
-      mapping_link: Ø¥بدأ التخطيط
+      mapping_link: Ø§بدأ التخطيط
     legal_babble:
       title_html: حقوق النشر والترخيص
       more_title_html: معرفة المزيد
       contributors_title_html: المساهمين
   welcome_page:
     title: أهلاً بك.
+    rules:
+      title: قواعد!
     questions:
       title: هل هناك أسئلة ؟
   fixthemap:
@@ -1412,6 +1422,11 @@ ar:
         الذي اُرسِلَ إليك فى رسالة تأكيد البريد الإلكتروني، كما <a href="%{reconfirm}">يُمكنك
         طلب رسالة تأكيد جديدة فى حالة عدم إستلام الاولى</a>.
       auth failure: آسف، لا يمكن الدخول بتلك التفاصيل.
+      auth_providers:
+        google:
+          title: قم بتسجيل الدخول عن طريق جوجل
+        facebook:
+          title: قم بتسجيل الدخول باستخدام الفيس بوك
     logout:
       title: تسجيل الخروج
       heading: الخروج من خريطة الشارع المفتوحة
@@ -1435,7 +1450,7 @@ ar:
       flash changed: كلمة المرور الخاصة بك قد تغيرت.
       flash token bad: لم نجد هذا النموذج، تحقق من الرابط ربما؟
     new:
-      title: Ø¥Ù\86شئ Ø­Ø³Ø§Ø¨Ø§Ù\8b
+      title: Ø£Ù\86شئ Ø­Ø³Ø§Ø¨Ø§
       no_auto_account_create: للأسف نحن غير قادرين في الوقت الحالي على إنشاء حساب
         لك تلقائيًا.
       contact_webmaster: يرجى الاتصال <a href="mailto:webmaster@openstreetmap.org">بمسؤول
@@ -1453,7 +1468,7 @@ ar:
         التفضيلات في وقت لاحق.
       password: 'كلمة السر:'
       confirm password: 'تأكيد كلمة المرور:'
-      continue: Ø¥Ù\86شئ Ø­Ø³Ø§Ø¨Ø§Ù\8b
+      continue: Ø£Ù\86شئ Ø­Ø³Ø§Ø¨Ø§
       terms accepted: نشكرك على قبول شروط المساهم الجديدة!
     terms:
       title: 'شروط المساهم:'
@@ -1762,6 +1777,8 @@ ar:
       title: شارك
       cancel: ألغ
       image: صورة
+      link: وصلة أو HTML
+      long_link: وصلة
       format: 'التنسيق:'
       scale: 'المقياس:'
       download: نزل
index 8a1802e5ac6d0aacd7bbe7faab8f4ee9c32121db..1076007eaf03327bd8be5c10faf8a02d994cef7c 100644 (file)
@@ -1072,9 +1072,9 @@ ast:
         de retirada de datos</a> o pidilo direutamente nel nuesu <a href="http://dmca.openstreetmap.org/">formulariu
         en llinia</a>.
       trademarks_title_html: <span id="trademarks"></span>Marques rexistraes
-      trademarks_1_html: OpenStreetMap ya'l logotipu de la lente son marques rexistraes
-        de la Fundación OpenStreetMap. Si tienes entrugues tocante al to usu de les
-        marques, mándales al <a href="http://wiki.osmfoundation.org/wiki/Licensing_Working_Group">grupu
+      trademarks_1_html: OpenStreetMap ,el logotipu de la lente y Estáu del Mapa son
+        marques rexistraes de la Fundación OpenStreetMap. Si tienes entrugues tocante
+        al usu de les marques, mándales al <a href="http://wiki.osmfoundation.org/wiki/Licensing_Working_Group">grupu
         de trabayu sobro llicencies</a>.
   welcome_page:
     title: ¡Bienveníu!
@@ -1445,6 +1445,9 @@ ast:
           track: Pista
           bridleway: Caleya
           cycleway: Carril bici
+          cycleway_national: Carril bici nacional
+          cycleway_regional: Carril bici rexonal
+          cycleway_local: Carril bici llocal
           footway: Camín peatonal
           rail: Ferrocarril
           subway: Metro
@@ -1497,6 +1500,9 @@ ast:
           private: Accesu priváu
           destination: Accesu pa destín
           construction: Carreteres en construcción
+          bicycle_shop: Tienda de bicicletes
+          bicycle_parking: Aparcamientu de bicicletes
+          toilets: Servicios
     richtext_area:
       edit: Editar
       preview: Vista previa
@@ -1766,6 +1772,9 @@ ast:
         windowslive:
           title: Anicia sesión con Windows Live
           alt: Anicia sesión con una cuenta de Windows Live
+        github:
+          title: Aniciar sesión con GitHub
+          alt: Aniciar sesión con una cuenta de GitHub
         yahoo:
           title: Aniciar sesión con Yahoo
           alt: Aniciar sesión con una OpenID de Yahoo
@@ -1971,6 +1980,8 @@ ast:
         gravatar: Usar Gravatar
         link: http://wiki.openstreetmap.org/wiki/Gravatar
         link text: ¿qué ye esto?
+        disabled: Desactivóse Gravatar.
+        enabled: Activóse la vista del to Gravatar.
       new image: Amestar una imaxe
       keep image: Mantener la imaxe actual
       delete image: Desaniciar la imaxe actual
@@ -2268,7 +2279,6 @@ ast:
         standard: Estándar
         cycle_map: Mapa ciclista
         transport_map: Mapa de tresportes
-        mapquest: MapQuest Open
         hot: Humanitariu
       layers:
         header: Capes del mapa
@@ -2329,11 +2339,23 @@ ast:
       instructions:
         continue_without_exit: Siguir en %{name}
         slight_right_without_exit: Llixeramente a la drecha haza %{name}
+        offramp_right_without_exit: Cueye la rampla a la drecha haza %{name}
+        onramp_right_without_exit: Xira a la drecha na rampla haza %{name}
+        endofroad_right_without_exit: Al final de la carretera xira a la drecha haza
+          %{name}
+        merge_right_without_exit: Xúnite a la drecha haza %{name}
+        fork_right_without_exit: Nel biforcu xira a la drecha haza %{name}
         turn_right_without_exit: Xira a la drecha haza %{name}
         sharp_right_without_exit: Fuerte a la drecha haza %{name}
         uturn_without_exit: Cambiu de sentíu en %{name}
         sharp_left_without_exit: Fuerte a la izquierda haza %{name}
         turn_left_without_exit: Xira a la izquierda haza %{name}
+        offramp_left_without_exit: Cueye la rampla a la izquierda haza %{name}
+        onramp_left_without_exit: Xira a la izquierda na rampla haza %{name}
+        endofroad_left_without_exit: Al final de la carretera xira a la izquierda
+          haza %{name}
+        merge_left_without_exit: Xúnite a la izquierda haza %{name}
+        fork_left_without_exit: Nel biforcu xira a la izquierda haza %{name}
         slight_left_without_exit: Llixeramente a la izquierda haza %{name}
         via_point_without_exit: (pel puntu)
         follow_without_exit: Siguir %{name}
diff --git a/config/locales/bn.yml b/config/locales/bn.yml
new file mode 100644 (file)
index 0000000..5899d30
--- /dev/null
@@ -0,0 +1,1190 @@
+# Messages for Bengali (বাংলা)
+# Exported from translatewiki.net
+# Export driver: phpyaml
+# Author: Aftabuzzaman
+# Author: Bellayet
+# Author: Bodhisattwa
+# Author: Ehsanulhb
+# Author: Kayser Ahmad
+# Author: Nasir8891
+# Author: Sayma Jahan
+# Author: Tauhid16
+# Author: Wikisagnik
+# Author: আজিজ
+# Author: এম আবু সাঈদ
+---
+bn:
+  time:
+    formats:
+      friendly: '%e %B %Y %H:%M-এ'
+  activerecord:
+    models:
+      acl: প্রবেশাধিকার নিয়ন্ত্রণ তালিকা
+      changeset: পরিবর্তনধার্য
+      changeset_tag: পরিবর্তনধার্য ট্যাগ
+      country: দেশ
+      diary_comment: ডাইরি মন্তব্য
+      diary_entry: ডাইরি ভুক্তি
+      friend: বন্ধু
+      language: ভাষা
+      message: বার্তা
+      node: সংযোগস্থল
+      node_tag: সংযোগস্থল ট্যাগ
+      notifier: নোটিফায়ার
+      old_node: পুরাতন সংযোগস্থল
+      old_node_tag: পুরাতন সংযোগস্থল ট্যাগ
+      old_relation: পুরনো সম্পর্ক
+      old_relation_member: পুরনো সম্পর্ক সদস্য
+      old_relation_tag: পুরনো সম্পর্ক ট্যাগ
+      old_way: পুরাতন পদ্ধতি
+      old_way_node: পুরাতন পদ্ধতির নোড
+      old_way_tag: পুরাতন পদ্ধতির ট্যাগ
+      relation: সম্পর্ক
+      relation_member: সম্পর্ক সদস্য
+      relation_tag: সম্পর্ক টাগ
+      session: সেশন
+      trace: ট্রেস
+      tracepoint: পথচিহ্ন বিন্দু
+      tracetag: ট্রেস ট্যাগ
+      user: ব্যবহারকারী
+      user_preference: ব্যবহারকারীর পছন্দ
+      user_token: ব্যবহারকারী টোকেন
+      way: রাস্তা
+      way_node: রাস্তার নোড
+      way_tag: রাস্তার ট্যাগ
+    attributes:
+      diary_comment:
+        body: মূলাংশ
+      diary_entry:
+        user: ব্যবহারকারী
+        title: বিষয়
+        latitude: অক্ষাংশ
+        longitude: দ্রাঘিমাংশ
+        language: ভাষা
+      friend:
+        user: ব্যবহারকারী
+        friend: বন্ধু
+      trace:
+        user: ব্যবহারকারী
+        visible: দৃশ্যমান
+        name: নাম
+        size: আকার
+        latitude: অক্ষাংশ
+        longitude: দ্রাঘিমাংশ
+        public: পাবলিক
+        description: বিবরণ
+      message:
+        sender: প্রেরক
+        title: শিরোনাম
+        body: বডি
+        recipient: প্রাপক
+      user:
+        email: ইমেইল
+        active: সক্রিয়
+        display_name: প্রদর্শনের জন্য নাম
+        description: বিবরণ
+        languages: ভাষা
+        pass_crypt: পাসওয়ার্ড
+  editor:
+    default: ডিফল্ট (বর্তমানে %{name})
+    potlatch:
+      name: পটল্যাচ ১
+      description: পটল্যাচ ১ (ব্রাউজার থেকে সম্পাদনা)
+    id:
+      name: আইডি
+      description: আইডি (ব্রাউজার সম্পাদকে)
+    potlatch2:
+      name: পটল্যাচ ২
+      description: পটল্যাচ ২ (ব্রাউজার থেকে সম্পাদনা)
+    remote:
+      name: রিমোট কন্ট্রোল
+      description: রিমোট কন্ট্রোল (JOSM অথবা Merkaartor)
+  browse:
+    created: তৈরি হয়েছে
+    closed: বন্ধ
+    created_html: <abbr title='%{title}'>%{time} আগে</abbr> তৈরি
+    closed_html: <abbr title='%{title}'>%{time} আগে</abbr> বন্ধ
+    created_by_html: '%{user} কর্তৃক <abbr title=''%{title}''>%{time} আগে</abbr> তৈরি'
+    deleted_by_html: '%{user} কর্তৃক <abbr title=''%{title}''>%{time}আগে</abbr> অপসারণ'
+    edited_by_html: '%{user} কর্তৃক <abbr title=''%{title}''>%{time} আগে</abbr> সম্পাদিত'
+    closed_by_html: '%{user} কর্তৃক <abbr title=''%{title}''>%{time} আগে</abbr> বন্ধ'
+    version: সংস্করণ
+    in_changeset: পরিবর্তনসমূহ
+    anonymous: নামহীন
+    no_comment: (কোন মন্তব্য নেই)
+    part_of: অংশ
+    download_xml: এক্সএমএল ডাউনলোড
+    view_history: ইতিহাস দেখুন
+    view_details: বিস্তারিত দেখুন
+    location: 'অবস্থান:'
+    changeset:
+      title: 'পরিবর্তনধার্য: %{id}'
+      belongs_to: লেখক
+      node: (%{count}টি) সংযোগস্থল
+      node_paginated: সংযোগস্থল (%{count}টির %{x}-%{y})
+      way: (%{count}টি) রাস্তা
+      way_paginated: পথসমূহ (%{count}টির %{x}-%{y})
+      relation: সম্পর্ক (%{count}টি)
+      relation_paginated: সম্পর্ক (%{count}টির %{x}-%{y})
+      comment: মন্তব্য (%{count}টি)
+      hidden_commented_by: '%{user} থেকে <abbr title=''%{exact_time}''>%{when} আগের</abbr>
+        মন্তব্য লুকান'
+      commented_by: <abbr title='%{exact_time}'>%{when} আগে</abbr> %{user} থেকে মন্তব্য
+      changesetxml: পরিবর্তনধার্য এক্সএমএল
+      osmchangexml: osmChange এক্সএমএল
+      feed:
+        title: পরিবর্তনধার্য %{id}
+        title_comment: পরিবর্তনধার্য %{id} - %{comment}
+      join_discussion: আলোচনায় যোগ দিতে প্রবেশ করুন
+      discussion: আলোচনা
+    node:
+      title: 'সংযোগস্থল: %{name}'
+      history_title: 'সংযোগস্থলের ইতিহাস: %{name}'
+    way:
+      title: 'রাস্তা: %{name}'
+      history_title: 'রাস্তা ইতিহাস: %{name}'
+      nodes: সংযোগস্থলসমূহ
+    relation:
+      title: 'সম্পর্ক: %{name}'
+      history_title: 'সম্পর্ক ইতিহাস: %{name}'
+      members: সদস্যবৃন্দ
+    relation_member:
+      entry_role: '%{type} %{name} %{role} হিসাবে'
+      type:
+        node: সংযোগস্থল
+        way: রাস্তা
+        relation: সম্পর্ক
+    containing_relation:
+      entry: সম্পর্ক %{relation_name}
+      entry_role: সম্পর্ক %{relation_name} (যখন %{relation_role})
+    not_found:
+      sorry: 'দুঃখিত, %{type} #%{id} পাওয়া যায়নি।'
+      type:
+        node: সংযোগস্থল
+        way: রাস্তা
+        relation: সম্পর্ক
+        changeset: পরিবর্তনধার্য
+        note: টীকা
+    timeout:
+      sorry: দুঃখিত, %{type} এর সাথে সম্পৃক্ত আইডি %{id}-র তথ্য, পুনরুদ্ধার করতে অতিরিক্ত
+        সময় লেগেছে।
+      type:
+        node: সংযোগস্থল
+        way: দিক
+        relation: সম্পর্ক
+        changeset: পরিবর্তনধার্য
+        note: টীকা
+    redacted:
+      redaction: সম্পর্ক %{id}
+      message_html: কোনও কারণে %{type}-এর %{version} সংস্করণটি দেখানো যাবে না। বিস্তারিত
+        জানতে %{redaction_link} দেখুন।
+      type:
+        node: সংযোগস্থল
+        way: দিক
+        relation: সম্পর্ক
+    start_rjs:
+      feature_warning: '%{num_features} বৈশিষ্ট্যগুলো লোড হচ্ছে, যা আপনার ব্রাউজারকে
+        ধীর অথবা সংবেদনহীন করতে পারে। আপনি কি এই তথ্য প্রদর্শনের ব্যপারে নিশ্চিত?'
+      load_data: তথ্য লোড করুন
+      loading: লোডিং...
+    tag_details:
+      tags: 'ট্যাগসমূহ:'
+      wiki_link:
+        key: '%{key} ট্যাগ এর উইকি বর্ণনা পাতা'
+        tag: '%{key}=%{value} ট্যাগ এর উইকি বর্ণনা পাতা'
+      wikidata_link: উইকিউপাত্ত উপাদানে %{page}
+      wikipedia_link: উইকিপিডিয়াতে %{page} প্রবন্ধ
+      telephone_link: '%{phone_number}-এ কল করুন'
+    note:
+      title: টীকা:%{id}
+      new_note: নতুন টীকা
+      description: 'বর্ণনা:'
+      open_title: 'অমীমাংসিত টীকা #%{note_name}'
+      closed_title: 'মীমাংসিত টীকা #%{note_name}'
+      hidden_title: 'লুকানো টীকা #%{note_name}'
+      open_by: '%{user} কর্তৃক <abbr title=''%{exact_time}''>%{when} আগে</abbr> তৈরি'
+      open_by_anonymous: বেনামী ব্যবহারকারী কর্তৃক <abbr title='%{exact_time}'>%{when}
+        আগে</abbr> তৈরি
+      commented_by: '%{user} কর্তৃক করা <abbr title=''%{exact_time}''>%{when} আগের</abbr>
+        মন্তব্য'
+      commented_by_anonymous: বেনামি ব্যবহারকারী কর্তৃক করা <abbr title='%{exact_time}'>%{when}
+        আগের</abbr> মন্তব্য
+      closed_by: '%{user} কর্তৃক <abbr title=''%{exact_time}''>%{when} আগে</abbr>
+        মীমাংসিত'
+      closed_by_anonymous: বেনামি ব্যবহারকারী দ্বারা <abbr title='%{exact_time}'>%{when}
+        আগে</abbr> সমাধানকৃত
+      reopened_by: '%{user} কর্তৃক <abbr title=''%{exact_time}''>%{when} আগে</abbr>
+        পুনঃসক্রিয়কৃত'
+      reopened_by_anonymous: বেনামি ব্যবহারকারী দ্বারা <abbr title='%{exact_time}'>%{when}
+        আগে</abbr> পুনঃসক্রিয়কৃত
+      hidden_by: '%{user} কর্তৃক <abbr title=''%{exact_time}''>%{when} আগে লুকায়িত</abbr>'
+    query:
+      title: বৈশিষ্ট্য অনুসন্ধান করুন
+      introduction: নিকটবর্তী বৈশিষ্ট্য খুঁজে পেতে মানচিত্রে ক্লিক করুন।
+      nearby: নিকটবর্তী বৈশিষ্ট্য
+      enclosing: আবদ্ধ বৈশিষ্ট্য
+  changeset:
+    changeset_paging_nav:
+      showing_page: '%{page}টি পাতা'
+      next: পরবর্তী »
+      previous: « পূর্ববর্তী
+    changeset:
+      anonymous: বেনামী ব্যবহারকারী
+      no_edits: (কোনো সম্পাদনা নেই)
+      view_changeset_details: পরিবর্তনধার্যে বিস্তারিত দেখুন
+    changesets:
+      id: আইডি
+      saved_at: সংরক্ষণ হয়েছে
+      user: ব্যবহারকারী
+      comment: মন্তব্য
+      area: এলাকা
+    list:
+      title: পরিবর্তনসমূহ
+      title_user: '%{user} দ্বারা পরিবর্তন ধার্য'
+      title_friend: আপনার বন্ধুদের পরিবর্তনসেট
+      title_nearby: আপনার কাছকাছি ব্যবহারকারীর পরিবর্তনসেট
+      empty: কোনো পরিবর্তনসেট পাওয়া যায়নি।
+      empty_area: এই এলাকায় কোনো পরিবর্তনসেট নেই।
+      empty_user: এই ব্যবহারকারীর দ্বারা আর কোনো পরিবর্তনসেট নেই।
+      no_more: আর কোনো পরিবর্তনসেট পাওয়া যায়নি।
+      no_more_area: এই এলাকায় কোনো পরিবর্তনসেট নেই।
+      no_more_user: এই ব্যবহারকারীর দ্বারা আর কোনো পরিবর্তনসেট নেই।
+      load_more: আরও লোড করুন
+    timeout:
+      sorry: দুঃখিত, আপনি যেই পরিবর্তনসেটটির জন্য আবেদন করছেন সেটি ফিরিয়ে আনতে আরও
+        সময় লাগবে।
+    rss:
+      title_all: ওপেনস্ট্রীটম্যাপ পরিবর্তনধার্য সম্পর্কিত  আলোচনা
+      title_particular: ওপেনস্ট্রীটম্যাপ পরিবর্তনধার্য %{changeset_id} সম্পর্কিত আলোচনা
+      comment: '%{author} কর্তৃক পরিবর্তনধার্য %{changeset_id}-এ নতুন মন্তব্য'
+      commented_at_html: '%{when} আগে থেকেই হালনাগাদকৃত'
+      commented_at_by_html: '%{user} কর্তৃক %{when} আগে হালনাগাদকৃত'
+      full: সম্পূর্ণ আলোচনা
+  diary_entry:
+    new:
+      title: নতুন দিনলিপির ভুক্তি
+      publish_button: প্রকাশ করুন
+    list:
+      title: ব্যবহারকারীর দিনলিপি
+      title_friends: বন্ধুর দিনলিপি
+      title_nearby: নিকটবর্তী ব্যবহারকারীর দিনলিপি
+      user_title: '%{user}-এর দিনলিপি'
+      in_language_title: '%{language} ভাষায় দিনলিপির ভুক্তি'
+      new: নতুন দিনলিপির ভুক্তি
+      new_title: আপনার ব্যবহারকারী দিনলিপিতে একটি নতুন ভুক্তি রচনা করুন
+      no_entries: কোনও দিনলিপির ভুক্তি নেই
+      recent_entries: সাম্প্রতিক দিনলিপির ভুক্তি
+      older_entries: পুরাতন ভুক্তি
+      newer_entries: নতুন ভুক্তি
+    edit:
+      title: দিনলিপির ভুক্তি সম্পাদনা করুন
+      subject: 'বিষয়:'
+      body: 'মূলাংশ:'
+      language: 'ভাষা:'
+      location: 'অবস্থান:'
+      latitude: 'অক্ষাংশ:'
+      longitude: 'দ্রাঘিমাংশ:'
+      use_map_link: মানচিত্র ব্যবহার করুন
+      save_button: সংরক্ষণ
+      marker_text: দিনলিপির ভুক্তির অবস্থান
+    view:
+      title: '%{user}-এর দিনলিপি | %{title}'
+      user_title: '%{user}-এর দিনলিপি'
+      leave_a_comment: মন্তব্য করুন
+      login_to_leave_a_comment: মন্তব্য করতে %{login_link} করুন
+      login: প্রবেশ
+      save_button: সংরক্ষণ
+    no_such_entry:
+      title: এমন কোন দিনলিপির ভুক্তি নেই
+      heading: '%{id} এই আইডি থেকে কোনও ভুক্তি নেই'
+      body: দুঃখিত, %{id} এই আইডি থেকে কোনও দিনলিপির ভুক্তি অথবা মন্তব্য নেই। দয়া
+        করে আপনার বানান যাচাই করুন, অথবা হতে পারে আপনি যে লিংকটিতে ক্লিক করেছেন তা
+        ভুল।
+    diary_entry:
+      comment_link: এই ভুক্তিতে মন্তব্য করুন
+      reply_link: এই ভুক্তির প্রত্যুত্তর দিন
+      comment_count:
+        zero: কোন মন্তব্য নেই
+        one: '%{count}টি মন্তব্য'
+        other: '%{count}টি মন্তব্য'
+      edit_link: এই ভুক্তি সম্পাদনা করুন
+      hide_link: এই ভুক্তি লুকান
+      confirm: নিশ্চিত করুন
+    diary_comment:
+      comment_from: '%{comment_created_at}-এ %{link_user} কর্তৃক মন্তব্য'
+      hide_link: এই মন্তব্যটি লুকান
+      confirm: নিশ্চিত করুন
+    location:
+      location: 'অবস্থান:'
+      view: দেখাও
+      edit: সম্পাদনা
+    feed:
+      user:
+        title: ওপেনস্ট্রীটম্যাপে %{user}-এর জন্য দিনলিপির ভুক্তি
+        description: ওপেনস্ট্রীটম্যাপে %{user}-এর সাম্প্রতিক দিনলিপির ভুক্তি
+      language:
+        title: ওপেনস্ট্রীটম্যাপে %{language_name} ভাষায় দিনলিপির ভুক্তি
+        description: ওপেনস্ট্রীটম্যাপ ব্যবহারকারীগণ কর্তৃক %{language_name} ভাষায়
+          সাম্প্রতিক দিনলিপির ভুক্তি
+      all:
+        title: ওপেনস্ট্রীটম্যাপ দিনলিপির ভুক্তি
+        description: ওপেনস্ট্রীটম্যাপ ব্যবহারকারীগণ কর্তৃক সাম্প্রতিক দিনলিপির ভুক্তি
+    comments:
+      post: পোস্ট
+      when: কখন
+      comment: মন্তব্য
+      ago: '%{ago} আগে'
+      newer_comments: নতুন মন্তব্য
+      older_comments: পুরাতন মন্তব্য
+  export:
+    title: রপ্তানি
+    start:
+      area_to_export: রপ্তানির এলাকা
+      manually_select: ম্যানুয়ালি একটি ভিন্ন জায়গা নির্বাচন করুন
+      format_to_export: রপ্তানির বিন্যাস
+      osm_xml_data: ওপেনস্ট্রীটম্যাপ এক্সএমএল উপাত্ত
+      map_image: মানচিত্র ছবি (মান্য স্তর দেখাও)
+      embeddable_html: অভ্যন্তরীণ HTML
+      licence: লাইসেন্স
+      export_details: ওপেনস্ট্রীটম্যাপের সমস্ত উপাত্ত <a href="http://opendatacommons.org/licenses/odbl/1.0/">ওপেন
+        ডাটা কমন্স ওপেন ডাটাবেস লাইসেন্সের</a> (ODbL) আওতায় প্রকাশিত।
+      too_large:
+        advice: 'যদি উপরের রপ্তানি ব্যর্থ হয়, দয়া করে নীচে তালিকাভুক্ত উৎসের কোন
+          একটি ব্যবহারের জন্য বিবেচনা করুন:'
+        planet:
+          title: ওএসএম জগৎ
+          description: সম্পূর্ণ ওপেনস্ট্রীটম্যাপ ডাটাবেসের নিয়মিত হালনাগাদের অনুলিপি
+        overpass:
+          title: ওভারপাস API
+        geofabrik:
+          title: জিওফ্যাব্রিক ডাউনলোড
+        other:
+          title: অন্যান্য উৎস
+          description: ওপেনস্ট্রীটম্যাপ উইকিতে তালিকাভুক্ত অতিরিক্ত সূত্র
+      options: বিকল্প
+      format: বিন্যাস
+      scale: স্কেল
+      max: সর্বোচ্চ
+      image_size: চিত্রের আকার
+      zoom: জুম
+      add_marker: মানচিত্রে একটি চিহ্নিতকারী যোগ করুন
+      latitude: 'অক্ষাংশ:'
+      longitude: 'দ্রাঘিমাংশ:'
+      output: আউটপুট
+      export_button: রপ্তানি
+  geocoder:
+    search:
+      title:
+        latlon: <a href="http://openstreetmap.org/">অভ্যন্তরীণ</a> থেকে ফলাফল
+        us_postcode: <a href="http://geocoder.us/">Geocoder.us</a থেকে ফলাফল
+        uk_postcode: <a href="http://www.npemap.org.uk/">NPEMap / FreeThe Postcode</a>
+          থেকে ফলাফল
+        ca_postcode: <a href="http://geocoder.ca/">Geocoder.CA</a> থেকে ফলাফল
+        osm_nominatim: <a href="http://nominatim.openstreetmap.org/">ওপেনস্ট্রীটম্যাপ
+          নমিনাতিম</a> থেকে ফলাফল
+        geonames: <a href="http://www.geonames.org/">জিওনেমস</a> থেকে ফলাফল
+        osm_nominatim_reverse: <a href="http://nominatim.openstreetmap.org/">ওপেনস্ট্রীটম্যাপ
+          নমিনাতিম</a> থেকে ফলাফল
+        geonames_reverse: <a href="http://www.geonames.org/">জিওনেমস</a> থেকে ফলাফল
+    search_osm_nominatim:
+      prefix:
+        aerialway:
+          station: বিমানপথ স্টেশন
+        aeroway:
+          aerodrome: বিমানশালা
+          apron: বর্হিবাস
+          gate: প্রবেশপথ
+          helipad: হেলিপ্যাড
+          runway: রানওয়ে
+          taxiway: ট্যাক্সিওয়ে
+          terminal: টার্মিনাল
+        amenity:
+          animal_shelter: পশুদের আশ্রয়স্থল
+          arts_centre: শিল্পকলা কেন্দ্র
+          atm: এটিএম
+          bank: ব্যাংক
+          bar: বার
+          bench: বেঞ্চ
+          bicycle_parking: সাইকেল পার্কিং
+          bicycle_rental: ভাড়ার সাইকেল
+          biergarten: বিয়ার বাগ
+          boat_rental: ভাড়ার নৌকা
+          brothel: পতিতালয়
+          bureau_de_change: পরিবর্তন ব্যুরো
+          bus_station: বাস স্টেশন
+          cafe: ক্যাফে
+          car_rental: ভাড়ার কার
+          car_sharing: শেয়ারিং কার
+          car_wash: গাড়ি ধোয়া
+          casino: ক্যাসিনো
+          charging_station: চার্জিং স্টেশন
+          childcare: শিশু যত্ন
+          cinema: সিনেমা
+          clinic: ক্লিনিক
+          clock: ঘড়ি
+          college: কলেজ
+          community_centre: কমিউনিটি সেন্টার
+          courthouse: আদালত
+          crematorium: শ্মশান
+          dentist: দন্তচিকিৎসক
+          doctors: ডাক্তার
+          dormitory: ছাত্রাবাস
+          drinking_water: পানীয় জল
+          driving_school: ড্রাইভিং স্কুল
+          embassy: দূতাবাস
+          emergency_phone: জরুরি ফোন
+          fast_food: ফাস্ট ফুড
+          ferry_terminal: ফেরিঘাট
+          fire_hydrant: ফায়ার হাইড্র্যান্ট
+          fire_station: অগ্নি নির্বাপন কেন্দ্র
+          food_court: খাবার দোকান
+          fountain: ঝরনা
+          fuel: জ্বালানি
+          gambling: জুয়াখেলার আড্ডা
+          grave_yard: কবরস্থান
+          gym: ব্যায়াম কেন্দ্র / জিমখানা
+          health_centre: স্বাস্থকেন্দ্র
+          hospital: হাসপাতাল
+          hunting_stand: শিকারশালা
+          ice_cream: আইসক্রিম
+          kindergarten: শিশুবিদ্যালয়
+          library: পাঠাগার
+          market: বাজার
+          marketplace: নগরচত্বর
+          monastery: আশ্রম
+          motorcycle_parking: মোটরসাইকেল  পার্কিং
+          nightclub: নৈশক্লাব
+          nursery: শিশুশালা
+          nursing_home: নার্সিংহোম
+          office: দপ্তর
+          parking: পার্কিং
+          parking_entrance: পার্কিং প্রবেশপথ
+          pharmacy: ঔষধালয়
+          place_of_worship: উপাসনালয়
+          police: পুলিশ
+          post_box: ডাকবাক্স
+          post_office: ডাকঘর
+          preschool: প্রাক-বিদ্যালয়
+          prison: কারাগার
+          pub: মদ্যশালা
+          public_building: সরকারি ভবন
+          reception_area: অভ্যর্থন এলাকা
+          restaurant: রেঁস্তোরা
+          retirement_home: অবসর গৃহ
+          school: বিদ্যালয়
+          shelter: আশ্রয়
+          shop: দোকান
+          shower: ঝরনা
+          social_centre: সামাজিক কেন্দ্র
+          social_club: সামাজিক সমিতি
+          social_facility: সামাজিক সুবিধা
+          studio: স্টুডিও
+          swimming_pool: সুইমিং পুল
+          taxi: ট্যাক্সি
+          telephone: সরকারি টেলিফোন
+          theatre: নাট্যশালা
+          toilets: পায়খানা
+          townhall: টাউনহল
+          university: বিশ্ববিদ্যালয়
+          vending_machine: ভেন্ডিং মেশিন
+          veterinary: ভেটেরিনারি সার্জারি
+          village_hall: গ্রামগৃহ
+          waste_basket: বর্জ্যদানি
+          waste_disposal: বর্জ্য পুনর্বাসন
+          youth_centre: যুব কেন্দ্র
+        boundary:
+          administrative: প্রশাসনিক সীমানা
+          national_park: জাতীয় উদ্যান
+          protected_area: সুরক্ষিত এলাকা
+        bridge:
+          aqueduct: জলপ্রণালী
+          suspension: ঝুলন্ত সেতু
+          swing: দোলনা সেতু
+          viaduct: ভায়াডাক্ট
+          "yes": সেতু
+        building:
+          "yes": ভবন
+        craft:
+          brewery: ভাটিখানা
+          carpenter: ছুতোর
+          electrician: বিদ্যুৎ মিস্তিরি
+          gardener: মালি
+          painter: চিত্রশিল্পী
+          photographer: আলোকচিত্ৰকর
+          plumber: নল মিস্তিরি
+          shoemaker: মুচি
+          tailor: দর্জি
+        emergency:
+          ambulance_station: রুগ্নবাহিকা স্টেশন
+          landing_site: জরুরি অবতরণ ক্ষেত্র
+          phone: জরুরি ফোন
+        highway:
+          abandoned: পরিত্যক্ত মহাসড়ক
+          bridleway: অঙ্কুশ পথ
+          bus_guideway: নির্দেশিত বাস পথ
+          bus_stop: বাস স্টপ
+          construction: নির্মীয়মাণ মহাসড়ক
+          cycleway: সাইকেল রাস্তা
+          elevator: লিফট
+          emergency_access_point: জরুরি প্রবেশ স্থল
+          footway: ফুটপাথ
+          milestone: মাইলফলক
+          path: পাথ
+          pedestrian: পাদচারী পথ
+          platform: প্লাটফর্ম
+          primary: প্রাথমিক সড়ক
+          primary_link: প্রাথমিক সড়ক
+          proposed: প্রস্তাবিত সড়ক
+          raceway: ধাবনপথ
+          residential: আবাসিক সড়ক
+          rest_area: বিশ্রামস্থল
+          road: রাস্তা
+          secondary: অপ্রধান সড়ক
+          secondary_link: অপ্রধান সড়ক
+          service: পার্শ্ব সড়ক
+          speed_camera: গতিমাপক ক্যামেরা
+          steps: ধাপ
+          street_lamp: রাস্তার বাতি
+          tertiary: প্রশাখা সড়ক
+          tertiary_link: প্রশাখা সড়ক
+          traffic_signals: ট্রাফিক সংকেত
+          trunk: মূল সড়ক
+          trunk_link: মূল সড়ক
+          unclassified: অশ্রেণীকৃত সড়ক
+          unsurfaced: কাঁচা সড়ক
+          "yes": সড়ক
+        historic:
+          archaeological_site: প্রত্নতাত্ত্বিক স্থান
+          battlefield: যুদ্ধক্ষেত্র
+          boundary_stone: সীমানাজ্ঞাপক পাথর
+          building: ঐতিহাসিক ভবন
+          castle: কেল্লা
+          church: গির্জা
+          city_gate: নগর দ্বার
+          citywalls: নগর প্রাচীর
+          fort: দুর্গ
+          heritage: ঐতিহ্য স্থান
+          house: বাড়ি
+          icon: আইকন
+          manor: জমিদারি
+          memorial: স্মারক
+          mine: খনি
+          monument: স্মৃতিস্তম্ভ
+          roman_road: রোমান সড়ক
+          ruins: ধ্বংসাবশেষ
+          stone: প্রস্তর
+          tomb: সমাধি
+          tower: মিনার
+        junction:
+          "yes": জংশন
+        landuse:
+          basin: অববাহিকা
+          cemetery: কবরস্থান
+          commercial: বানিজ্যিক এলাকা
+          farm: খামার
+          farmland: কৃষিজমি
+          forest: অরণ্য
+          garages: গ্যারেজ
+          grass: ঘাস
+          greenfield: তৃণভূমি
+          industrial: শিল্পাঞ্চল
+          meadow: তৃণভূমি
+          military: সামরিক এলাকা
+          mine: খনি
+          orchard: ফলবাগিচা
+          quarry: আকরিক
+          railway: রেলপথ
+          recreation_ground: চিত্তবিনোদন মাঠ
+          reservoir: জলাধার
+          reservoir_watershed: জলাধারের বিভাগরেখা
+          residential: আবাসিক এলাকা
+          road: সড়ক এলাকা
+          village_green: হরিত গ্রাম
+          vineyard: আঙুর খেত
+          "yes": ব্যবহার্য ভূমি
+        leisure:
+          beach_resort: সৈকতীয় রিসোর্ট
+          club: ক্লাব
+          common: সাধারণ ভূমি
+          dog_park: কুকুর উদ্যান
+          fishing: মৎস শিকারের এলাকা
+          garden: বাগান
+          golf_course: গল্ফ মাঠ
+          nature_reserve: সংরক্ষিত প্রাকৃতিক ভূমি
+          park: উদ্যান
+          playground: খেলার মাঠ
+          recreation_ground: চিত্তবিনোদন মাঠ
+          resort: রিসোর্ট
+          sports_centre: ক্রীড়া কেন্দ্র
+          stadium: ক্রিড়াঙ্গন
+          swimming_pool: সুইমিং পুল
+          water_park: বারি উদ্যান
+          "yes": অবসর
+        man_made:
+          lighthouse: বাতিঘর
+          pipeline: পাইপলাইন
+          tower: টাওয়ার
+          works: কারখানা
+          "yes": মনুষ্য-নির্মিত
+        military:
+          airfield: সামরিক বিমানপোত
+          barracks: সেনানিবাস
+        mountain_pass:
+          "yes": গিরিপথ
+        natural:
+          bay: উপসাগর
+          beach: সৈকত
+          cape: অন্তরীপ
+          cave_entrance: গুহা প্রবেশিকা
+          cliff: দুরারোহ পর্বতগাত্র
+          crater: গর্ত
+          dune: বালিয়াড়ি
+          fjord: সমুদ্রের খাড়ি
+          forest: অরণ্য
+          geyser: উষ্ণপ্রস্রবণ
+          glacier: হিমবাহ
+          grassland: চারণক্ষেত্র
+          heath: স্বাস্থ্য
+          hill: পাহাড়
+          island: দ্বীপ
+          land: জমি
+          marsh: দলদল
+          moor: প্রাস্তর
+          mud: কাদা
+          peak: শৃঙ্গ
+          point: স্থানবিন্দু
+          reef: প্রবালপ্রাচীর
+          ridge: শৈলশিরা
+          rock: শিলা
+          sand: বালু
+          scrub: ঝাড়ভূমি
+          spring: বসন্ত
+          stone: পাথর
+          strait: প্রণালী
+          tree: গাছ
+          valley: উপত্যকা
+          volcano: আগ্নেয়গিরি
+          water: পানি
+          wetland: জলাভূমি
+        office:
+          accountant: হিসাবরক্ষক
+          administrative: প্রশাসন
+          architect: স্থপতি
+          company: কোম্পানি
+          employment_agency: কর্মসংস্থান সংস্থা
+          estate_agent: এস্টেট এজেন্ট
+          government: সরকারি দপ্তর
+          insurance: বিমা দপ্তর
+          lawyer: উকিল
+          ngo: এনজিও দপ্তর
+          telecommunication: টেলিযোগাযোগ দপ্তর
+          travel_agent: ভ্রমণ দালাল
+          "yes": দপ্তর
+        place:
+          block: ব্লক
+          airport: বিমানবন্দর
+          city: নগর
+          country: দেশ
+          county: প্রদেশ
+          farm: খামার
+          hamlet: পল্লি
+          house: বাড়ি
+          houses: বাড়িগুলো
+          island: দ্বীপ
+          islet: ক্ষুদ্র দ্বীপ
+          isolated_dwelling: বিচ্ছিন্ন বাসস্থান
+          locality: বসতি
+          moor: প্রাস্তর
+          municipality: পৌরসভা
+          neighbourhood: শহরতলি
+          postcode: ডাক সংখ্যা
+          region: অঞ্চল
+          sea: সাগর
+          state: রাজ্য
+          subdivision: মহকুমা
+          suburb: উপনগর
+          town: শহর
+          unincorporated_area: অনিগমিত এলাকা
+          village: গ্রাম
+          "yes": স্থান
+        railway:
+          abandoned: পরিত্যক্ত রেলপথ
+          construction: নির্মীয়মাণ রেলপথ
+          disused: অব্যবহৃত রেলপথ
+          disused_station: অব্যবহৃত রেল স্টেশন
+          historic_station: ঐতিহাসিক রেল স্টেশন
+          junction: রেল জংশন
+          monorail: মনোরেল
+          narrow_gauge: সংকীর্ণ গেজ রেল
+          platform: রেলওয়ে প্লাটফর্ম
+          preserved: সংরক্ষিত রেলপথ
+          proposed: প্রস্তাবিত রেলপথ
+          station: রেল স্টেশন
+          stop: রেল থামার স্থান
+          subway: ভূগর্ভস্থ পথ
+          subway_entrance: ভূগর্ভস্থ পথের প্রবেশিকা
+          tram: ট্রামপথ
+        shop:
+          antiques: প্রাচীন শিল্পকর্ম
+          art: শিল্পকলা সংক্রান্ত দোকান
+          bakery: বেকারি
+          beauty: প্রসাধনীর দোকান
+          beverages: পানীয় দোকান
+          bicycle: বাইসাইকেল দোকান
+          books: বইয়ের দোকান
+          butcher: মাংসবিক্রেতা
+          carpet: কার্পেটের দোকান
+          clothes: কাপড়ের দোকান
+          computer: কম্পিউটারের দোকান
+          confectionery: মিষ্টান্নের দোকান
+          convenience: কনভেনিয়েন্স স্টোর
+          copyshop: কপি শপ
+          cosmetics: প্রসাধনী সামগ্রীর দোকান
+          deli: যন্ত্রাংশ
+          discount: সস্তা সামগ্রীর দোকান
+          doityourself: নিজে-করো
+          dry_cleaning: কাপড় ধোয়ার দোকান
+          electronics: বৈদ্যুতিক জিনিসের দোকান
+          estate_agent: এস্টেট এজেন্ট
+          farm: কৃষি ভাণ্ডার
+          fashion: ফ্যাশন সামগ্রীর দোকান
+          fish: মাছের দোকান
+          florist: ফুলওয়ালা
+          food: খাবারের দোকান
+          funeral_directors: অন্ত্যেষ্টিক্রিয়া পরিচালকবৃন্দ
+          furniture: আসবাবপত্র
+          gallery: চিত্রশালা
+          garden_centre: বাগান কেন্দ্র
+          general: সাধারণ দোকান
+          gift: উপহারের দোকান
+          greengrocer: সবজিওয়ালা
+          grocery: মুদি দোকান
+          hairdresser: নাপিত
+          hardware: যন্ত্রাংশের দোকান
+          hifi: হাই-ফাই
+          insurance: বিমা
+          jewelry: গহনার দোকান
+          laundry: ধোপার দোকান
+          mall: মল
+          market: বাজার
+          mobile_phone: মোবাইল ফোনের দোকান
+          motorcycle: মোটোরসইকেলের দোকান
+          music: সঙ্গীতের দোকান
+          newsagent: সংবাদপত্র বিক্রেতা
+          optician: চশমা বিক্রেতা
+          organic: জৈব খাদ্যের দোকান
+          pharmacy: ঔষধালয়
+          photo: ছবির দোকান
+          salon: সালোন
+          second_hand: পুরনো-সামগ্রীর দোকান
+          shoes: জুতোর দোকান
+          shopping_centre: বিপনি কেন্দ্র
+          sports: ক্রীড়াসামগ্রীর দোকান
+          stationery: স্টেশনারি দোকান
+          supermarket: অধিবিপণী
+          tailor: দর্জি
+          toys: খেলনার দোকান
+          travel_agency: ভ্রমণ দালাল
+          "yes": দোকান
+        tourism:
+          attraction: আকর্ষণ
+          guest_house: অতিথি বাড়ি
+          hostel: হোস্টেল
+          hotel: হোটেল
+          information: তথ্য
+          motel: মোটেল
+          museum: যাদুঘর
+          picnic_site: বনভোজনের স্থান
+          zoo: চিড়িয়াখানা
+        tunnel:
+          culvert: সাঁকো
+          "yes": সুড়ঙ্গ
+        waterway:
+          artificial: কৃত্রিম জলপথ
+          boatyard: নৌকাক্ষেত্র
+          canal: খাল
+          dam: বাঁধ
+          derelict_canal: পরিত্যক্ত খাল
+          ditch: খাই
+          dock: ফেরিঘাট
+          drain: নালা
+          lock: বন্ধ
+          lock_gate: ফটক বন্ধ
+          mooring: নঙ্গরাবদ্ধকরণ
+          river: নদী
+          wadi: ওয়াদি
+          waterfall: জলপ্রপাত
+          "yes": জলপথ
+      admin_levels:
+        level2: রাষ্ট্রের সীমানা
+        level4: রাজ্যের সীমানা
+        level5: অঞ্চলের সীমানা
+        level6: প্রদেশের সীমানা
+        level8: নগরের সীমান
+        level9: গ্রামের সীমানা
+        level10: উপনগরের সীমানা
+    description:
+      title:
+        osm_nominatim: <a href="http://nominatim.openstreetmap.org/">ওপেনস্ট্রীটম্যাপ
+          Nominatim</a> থেকে অবস্থান
+        geonames: <a href="http://www.geonames.org/">জিওনেম্স</a> থেকে অবস্থান
+      types:
+        cities: নগর
+        towns: শহর
+        places: স্থান
+    results:
+      no_results: ফলাফল খুঁজে পাওয়া যায়নি
+      more_results: আরও ফলাফল
+  layouts:
+    logo:
+      alt_text: ওপেনস্ট্রীটম্যাপ লোগো
+    home: নিড় অবস্থানে যান
+    logout: প্রস্থান
+    log_in: প্রবেশ
+    log_in_tooltip: একটি বিদ্যমান অ্যাকাউন্ট দিয়ে প্রবেশ করুন
+    sign_up: যোগ দিন
+    start_mapping: মানচিত্রকরণ শুরু করুন
+    sign_up_tooltip: সম্পাদনা করতে একটি অ্যাকাউন্ট তৈরি করুন
+    edit: সম্পাদনা
+    history: ইতিহাস
+    export: রপ্তানি
+    data: উপাত্ত
+    export_data: উপাত্ত রপ্তানি করুন
+    gps_traces: জিপিএস ট্রেস
+    gps_traces_tooltip: জিপিএস ট্রেস ব্যাবস্থাপনা
+    user_diaries: ব্যবহারকারীর দিনলিপি
+    user_diaries_tooltip: ব্যবহারকারী দিনলিপি দেখুন
+    edit_with: '%{editor} দিয়ে সম্পাদনা করুন'
+    tag_line: মুক্ত উইকি বিশ্ব মানচিত্র
+    intro_header: ওপেনস্ট্রীটম্যাপে স্বাগতম!
+    intro_text: ওপেনস্ট্রীটম্যাপ বিশ্বের, একটি মানচিত্র; যা আপনার মতো মানুষের দ্বারা
+      নির্মিত এবং এটি মুক্ত লাইসেন্সের অধীনে বিনামূল্যে ব্যবহারযোগ্য।
+    intro_2_create_account: একটি ব্যবহারকারী অ্যাকাউন্ট তৈরি করুন
+    partners_html: হোস্টিং %{ucl}, %{ic} ও %{bytemark}, এবং অন্যান্য %{partners} কর্তৃক
+      সমর্থিত।
+    partners_ic: ইম্পেরিয়াল মহাবিদ্যালয় লন্ডন
+    partners_partners: সহযোগীগণ
+    help: সাহায্য
+    about: পরিচিতি
+    copyright: মেধাসত্ব
+    community: সম্প্রদায়
+    community_blogs: সম্প্রদায়ের ব্লগ
+    community_blogs_title: ওপেনস্ট্রীটম্যাপ সম্প্রদায়ের সদস্যগণের ব্লগ
+    foundation: ফাউন্ডেশন
+    foundation_title: ওপেনস্ট্রীটম্যাপ ফাউন্ডেশন
+    make_a_donation:
+      title: আর্থিক অনুদান দিয়ে ওপেনস্ট্রীটম্যাপকে সাহায্য করুন
+      text: দান করুন
+    learn_more: আরও পড়ুন
+    more: আরও
+  license_page:
+    foreign:
+      title: এই অনুবাদ সম্পর্কে
+      english_link: মূল ইংরেজি
+    native:
+      title: এই পাতা সম্পর্কে
+      text: আপনি মেধাস্বত্ব পৃষ্ঠার ইংরেজি সংস্করণ দেখছেন। আপনি এই পৃষ্ঠার %{native_link}-এ
+        ফিরে যেতে পারেন অথবা আপনি মেধাস্বত্ব এবং %{mapping_link} সম্পর্কে পড়া বন্ধ
+        করতে পারেন।
+      native_link: THIS_LANGUAGE_NAME_HERE সংস্করণ
+      mapping_link: মানচিত্রকরণ শুরু করুন
+    legal_babble:
+      title_html: কপিরাইট ও লাইসেন্স
+      intro_1_html: |-
+        ওপেনস্ট্রীটম্যাপ<sup><a href="#trademarks">&reg;</a></sup> একটি <i>মুক্ত উপাত্ত</i> যা <a
+        href="http://osmfoundation.org/">ওপেনস্ট্রীটম্যাপ ফাউন্ডেশন কর্তৃক</a> (OSMF) <a
+        href="http://opendatacommons.org/licenses/odbl/">মুক্ত উপাত্ত কমন্স মুক্ত তথ্যভিত লাইসেন্সের</a> (ODbL) আওতায় লাইসেন্সকৃত।
+      contributors_title_html: আমাদের অবদানকারীগণ
+      infringement_title_html: কপিরাইট লঙ্ঘন
+      trademarks_title_html: <span id="trademarks"></span>ট্রেডমার্ক
+  welcome_page:
+    title: স্বাগতম!
+    whats_on_the_map:
+      title: মানচিত্রে কী আছে
+    basic_terms:
+      title: মানচিত্রকরণের জন্য মৌলিক শর্তাবলী
+    rules:
+      title: নিয়মাবলী!
+    questions:
+      title: কোনও প্রশ্ন?
+    start_mapping: মানচিত্রকরণ শুরু করুন
+    add_a_note:
+      title: সম্পাদনার সময় নেই? একটি টীকা যোগ করুন!
+  fixthemap:
+    how_to_help:
+      join_the_community:
+        title: সম্প্রদায়ে যোগ দিন
+    other_concerns:
+      title: অন্যান্য উদ্বেগ
+  help_page:
+    welcome:
+      url: /স্বাগতম
+      title: ওএসএম-এ স্বাগতম
+    beginners_guide:
+      url: http://wiki.openstreetmap.org/wiki/Bn:Beginners%27_guide
+      title: আরম্ভকারী সহায়িকা
+    help:
+      url: https://help.openstreetmap.org/
+      title: help.openstreetmap.org
+    wiki:
+      url: http://wiki.openstreetmap.org/
+      title: wiki.openstreetmap.org
+  about_page:
+    next: পরবর্তী
+    copyright_html: <span>&copy;</span>ওপেনস্ট্রীটম্যাপ<br>অবদানকারী
+    local_knowledge_title: স্থানীয় অভিজ্ঞতা
+    community_driven_title: সম্প্রদায় চালক
+    open_data_title: মুক্ত তথ্য
+    legal_title: আইনগত
+    partners_title: অংশীদার
+  notifier:
+    diary_comment_notification:
+      subject: '[OpenStreetMap] %{user} আপনার দিনলিপি ভুক্তিতে মন্তব্য করেছেন'
+      hi: হাই %{to_user},
+    message_notification:
+      hi: হাই %{to_user},
+    friend_notification:
+      had_added_you: '%{user} আপনাকে ওপেনস্ট্রীটম্যাপে বন্ধু হিসেবে যোগ করেছেন।'
+      see_their_profile: আপনি %{userurl}-এ তাদের প্রোফাইল দেখতে পারেন।
+    gpx_notification:
+      greeting: হাই,
+      with_description: বিবরণ সহ
+      and_the_tags: 'এবং নিম্নলিখিত ট্যাগ:'
+    signup_confirm:
+      subject: '[OpenStreetMap] ওপেনস্ট্রীটম্যাপে স্বাগতম'
+    email_confirm:
+      subject: '[OpenStreetMap] আপনার ইমেইল ঠিকানা নিশ্চিত করুন'
+    email_confirm_plain:
+      greeting: হাই,
+      click_the_link: এটি যদি আপনি হন, দয়া করে পরিবর্তন নিশ্চিত করতে নিচের লিংকে
+        ক্লিক করুন।
+    email_confirm_html:
+      greeting: হাই,
+      click_the_link: এটি যদি আপনি হন, দয়া করে পরিবর্তন নিশ্চিত করতে নিচের লিংকে
+        ক্লিক করুন।
+    lost_password:
+      subject: '[ওপেনস্ট্রীটম্যাপ] পাসওয়ার্ড পুনঃধার্য করার অনুরোধ'
+    lost_password_plain:
+      greeting: হাই,
+      click_the_link: এটি যদি আপনি হন, তবে পাসওয়ার্ড পুনঃধার্য করতে দয়া করে নিচের
+        লিংকে ক্লিক করুন।
+    lost_password_html:
+      greeting: হাই,
+      click_the_link: এটি যদি আপনি হন, তবে পাসওয়ার্ড পুনঃধার্য করতে দয়া করে নিচের
+        লিংকে ক্লিক করুন।
+    note_comment_notification:
+      anonymous: একজন বেনামি ব্যবহারকারী
+      greeting: হাই,
+      details: টীকাটি সম্পর্কে আরও বিস্তারিত %{url|এখানে} পাওয়া যাবে।
+    changeset_comment_notification:
+      greeting: হাই,
+      details: পরিবর্তনধার্য সম্পর্কে আরও বিস্তারিত %{url|এখানে} পাওয়া যাবে।
+  message:
+    inbox:
+      title: ইনবক্স
+      my_inbox: আমার ইনবক্স
+      outbox: আউটবক্স
+      subject: বিষয়
+      date: তারিখ
+      people_mapping_nearby: কাছাকাছি অবদানকারী
+    message_summary:
+      unread_button: অপঠিত হিসেবে চিহ্নিত করুন
+      read_button: পঠিত হিসেবে চিহ্নিত করুন
+      reply_button: প্রত্যুত্তর
+  site:
+    key:
+      table:
+        entry:
+          cycleway_national: জাতীয় সাইকেলের রাস্তা
+          cycleway_regional: আঞ্চলিক সাইকেলের রাস্তা
+          cycleway_local: স্থানীয় সাইকেলের রাস্তা
+          bicycle_shop: সাইকেলের দোকান
+          bicycle_parking: সাইকেল পার্কিং
+          toilets: পায়খানা
+  trace:
+    create:
+      upload_trace: জিপিএস অনুসরণ আপলোড
+      trace_uploaded: আপনার জিপিএক্স ফাইলটি আপলোড হয়েছে এবং ডাটাবেইজ এ অন্তর্ভুক্তির
+        জন্য অপেক্ষা করছে। সাধারণত, এটি আধা ঘন্টার মধ্যেই সম্পন্ন হয় এবং সমাপ্ত হতেই
+        আপনার কাছে একটি ই-মেইল পৌছে যাবে।
+    edit:
+      title: অনুসরণ সম্পাদনা %{name}
+      heading: অনুসরণ সম্পাদনা %{name}
+      filename: 'ফাইলের নাম:'
+      download: ডাউনলোড
+      uploaded_at: 'আপলোড হয়েছে:'
+      points: 'পয়েন্ট:'
+      start_coord: 'প্রারম্ভের কোঅর্ডিনেট:'
+      map: মানচিত্র
+      edit: সম্পাদনা
+      owner: 'মালিক:'
+      description: 'বিবরণ:'
+      tags: 'ট্যাগসমূহ:'
+      visibility_help: এটার মানে কি?
+    trace_form:
+      upload_gpx: 'জিপিএক্স ফাইল আপলোড:'
+      description: 'বিবরণ:'
+      tags: 'ট্যাগসমূহ:'
+      visibility_help: এটার মানে কি?
+      upload_button: আপলোড
+      help: সাহায্য
+    trace_header:
+      upload_trace: অনুসরণ আপলোড
+      see_all_traces: সব অনুসরণগুলো দেখুন
+      see_your_traces: আপনার সব অনুসরণগুলো দেখুন
+      traces_waiting: আপনার %{count}টি অনুসরণ আপলোড হতে বাকি আছে। দয়া করে এগুলো আপলোড
+        হওয়া পর্যন্ত অপেক্ষা করুন, যেন অন্য ব্যবহারকারীদের অনুসরণ আপলোড করার সুযোগ
+        দেয়া যায়।
+    trace_optionals:
+      tags: ট্যাগসমূহ
+    view:
+      title: '%{name} অনুসরণটি দেখছেন'
+      heading: '%{name} অনুসরণটি দেখছেন'
+      pending: অমিমাংসিত
+      filename: 'ফাইলের নাম:'
+      download: ডাউনলোড
+      uploaded: 'আপলোড হয়েছে:'
+      points: 'পয়েন্ট:'
+      start_coordinates: 'প্রারম্ভের কোঅর্ডিনেট:'
+      map: মানচিত্র
+      edit: সম্পাদনা
+      owner: 'মালিক:'
+      description: 'বিবরণ:'
+      tags: 'ট্যাগসমূহ:'
+      none: কোনটিই নয়
+      edit_track: এই অনুসরণটি সম্পাদনা করুন
+      delete_track: এই অনুসরণটি মুছে ফেলুন
+      trace_not_found: অনুসরণ পাওযা যায়নি।
+    trace_paging_nav:
+      showing_page: '%{page} পাতা'
+    trace:
+      pending: অমিমাংসিত
+      count_points: '%{count} পয়েন্ট'
+      ago: '%{time_in_words_ago} পূর্বে'
+      more: আরও
+      trace_details: অনুসরণের বিস্তারিত দেখুন
+      view_map: মানচিত্র দেখুন
+      edit: সম্পাদনা
+      edit_map: মানচিত্র সম্পাদনা
+      identifiable: শনাক্তকরণযোগ্য
+      private: ব্যাক্তিগত
+      trackable: অনুসরণযোগ্য
+      by: দ্বারা
+      map: মানচিত্র
+    list:
+      your_traces: আপনার জিপিএস অনুসরণ
+    offline_warning:
+      message: জিপিএক্স ফাইল আপলোড বর্তমানে সম্ভব নয়
+    offline:
+      message: জিপিএক্স ফাইল সংরক্ষণ এবং আপলোড বর্তমানে সম্ভব নয়
+  user:
+    login:
+      auth_providers:
+        github:
+          title: গিটহাব দিয়ে প্রবেশ করুন
+          alt: একটি গিটহাব অ্যাকাউন্ট দিয়ে প্রবেশ করুন
+    terms:
+      agree: একমত
+      legale_select: 'আপনার দেশ বাছাই করুন:'
+      legale_names:
+        france: ফ্রান্স
+        italy: ইতালি
+        rest_of_world: অন্যান্য দেশসমূহ
+    view:
+      description: বিবরণ
+      block_history: সক্রিয় বাধাসমূহ
+      moderator_history: প্রদত্ত বাধাগুলি
+      create_block: এই ব্যবহারকারীকে বাধা দাও
+      activate_user: এই ব্যবহাকারীকে সক্রিয় করুন
+      deactivate_user: এই ব্যবহারকারীকে নিষ্ক্রিয় করুন
+      confirm_user: এই ব্যবহারকারীকে নিশ্চিত করুন
+      hide_user: এই ব্যবহারকারীকে লুকান
+      unhide_user: এই ব্যবহাকারীকে দেখান
+      delete_user: এই ব্যবহাকারীকে অপসারণ করুন
+    confirm:
+      button: নিশ্চিত করুন
+    go_public:
+      flash success: আপনার সকল সম্পাদনা এখন উন্মুক্ত, এবং এখন আপনার সম্পাদনের অনুমতি
+        রয়েছে।
+  user_role:
+    filter:
+      not_an_administrator: শুধুমাত্র এডমিনিস্ট্রেটরই ব্যবহারকারীর দায়িত্ব প্রদান
+        করতে পারে এবং আপনি এডমিনিষ্ট্রেটর নন।
+      not_a_role: উক্ত `%{role}' টি কোন সঠিক দায়িত্ব নয়।
+      already_has_role: এই ব্যবহারকারী %{role} দায়িত্বটি এখনো আছে।
+      doesnt_have_role: এই ব্যবহারকারীর %{role} দায়িত্বটি নেই।
+    grant:
+      title: দায়িত্ব প্রদানকরণ নিশ্চিত করুন
+      heading: দায়িত্ব প্রদানকরণ নিশ্চিত করুন
+      are_you_sure: আপনি কি `%{name}' ব্যবহারকারী কে `%{role}' দায়িত্বটি দিতে চান?
+      confirm: নিশ্চিত করুন
+      fail: '`%{name}'' ব্যবহারকারীর `%{role}'' দায়িত্বটি প্রদান সম্ভব হয় নি। দয়া
+        করে দেখুন যে এই ব্যবহারকারী এবং দায়িত্বটি সঠিক কিনা।'
+    revoke:
+      title: দায়িত্ব বাতিলকরণ নিশ্চিত করুন
+      heading: দায়িত্ব বাতিলকরণ নিশ্চিত করুন
+      are_you_sure: আপনি কি নিশ্চিতভাবে `%{name}' ব্যবহারকারীর উক্ত `%{role}' দায়িত্বটি
+        বাতিল করতে চান?
+      confirm: নিশ্চিত করুন
+      fail: '`%{name}'' ব্যবহারকারীর `%{role}'' দায়িত্বটি বাতিল অযোগ্য। দয়া করে
+        দেখুন যে এই ব্যবহারকারী এবং দায়িত্বটি সঠিক কিনা।'
+  user_block:
+    partial:
+      next: পরবর্তী »
+      previous: « পূর্ববর্তী
+    show:
+      status: স্থিতি
+      show: দেখাও
+      edit: সম্পাদনা
+      confirm: আপনি কি নিশ্চিত?
+  javascripts:
+    notes:
+      new:
+        add: টীকাযুক্ত করুন
+      show:
+        hide: লুকান
+        resolve: মিমাংসা করুন
+        reactivate: পুনঃসক্রিয়
+    directions:
+      errors:
+        no_place: দুঃখিত - এই স্থানটি খুঁজে পাওয়া যায়নি।
+      instructions:
+        continue_without_exit: '%{name}-এ যেতে থাকুন'
+        slight_right_without_exit: '%{name}-এ সামান্য ডান দিকে সরান'
+        turn_right_without_exit: '%{name}-এ ডানদিকে মোড় নিন'
+        turn_left_without_exit: '%{name}-এ ডানদিকে মোড় নিন'
+        slight_left_without_exit: '%{name}-এ সামান্য বামে'
+        via_point_without_exit: (বিন্দুর মাধ্যমে)
+        follow_without_exit: '%{name} অনুসরণ করুন'
+        start_without_exit: '%{name}-এর শেষে শুরু'
+        destination_without_exit: গন্তব্যে পৌঁছানো
+        against_oneway_without_exit: '%{name}-এ একমুখীর বিরুদ্ধে যান'
+        end_oneway_without_exit: '%{name}-এর একমুখী শেষ'
+        unnamed: নামহীন সড়ক
+      time: সময়
+    query:
+      node: সংযোগস্থল
+      way: রাস্তা
+      relation: সম্পর্ক
+      nothing_found: বৈশিষ্ট্য খুঁজে পাওয়া যায়নি
+  redaction:
+    edit:
+      description: বিবরণ
+      heading: সম্পাদনা সম্পাদন করুন
+      submit: সম্পাদন সংরক্ষণ করুন
+      title: সম্পাদনা সম্পাদন করুন
+    index:
+      empty: প্রদর্শন করার মতো সম্পাদন নেই।
+      heading: সম্পাদন সমূহের তালিকা
+      title: সম্পাদন সমূহের তালিকা
+    new:
+      description: বিবরণ
+      heading: নতুন সম্পাদনের জন্য তথ্য লিখুন
+      submit: সম্পাদন তৈরি করুন
+      title: নতুন সম্পাদন তৈরি করা হচ্ছে
+    show:
+      description: 'বিবরণ:'
+      confirm: আপনি কি নিশ্চিত?
+    update:
+      flash: পরিবর্তন সংরক্ষিত।
+...
index d44485e84a522ed037b1830b9973155870de8ca1..fdbe41dbb0fe4ef5cd4915e30272ff3374713760 100644 (file)
@@ -1467,6 +1467,8 @@ br:
           track: Roudenn
           bridleway: Hent evit kezeg
           cycleway: Roudenn divrodegoù
+          cycleway_national: roudenn vroadel evit an divrodegoù
+          cycleway_local: roudenn lec'hel evit an divrodegoù
           footway: Hent evit an dud war droad
           rail: Hent-houarn
           subway: Linenn vetro
@@ -1519,6 +1521,8 @@ br:
           private: Moned prevez
           destination: Moned d'ar pal
           construction: Hentoù war ar stern
+          bicycle_shop: Stal varc'hoù-houarn
+          toilets: Privezioù
     richtext_area:
       edit: Aozañ
       preview: Rakwelet
@@ -1923,16 +1927,16 @@ br:
         revoke:
           administrator: Disteurel ar moned merour
           moderator: Disteurel ar moned habaskaer
-      block_history: stankadurioù resevet
-      moderator_history: stankadurioù roet
+      block_history: stankadurioù oberiant
+      moderator_history: Stankadurioù roet
       comments: evezhiadennoù
-      create_block: stankañ an implijer-mañ
-      activate_user: gweredekaat an implijer-mañ
-      deactivate_user: diweredekaat an implijer-mañ
-      confirm_user: kadarnaat an implijer-mañ
-      hide_user: kuzhat an implijer-mañ
+      create_block: Stankañ an implijer-mañ
+      activate_user: Gweredekaat an implijer-mañ
+      deactivate_user: Diweredekaat an implijer-mañ
+      confirm_user: Kadarnaat an implijer-mañ
+      hide_user: Kuzhat an implijer-mañ
       unhide_user: Diguzhat an implijer-mañ
-      delete_user: dilemel an implijer-mañ
+      delete_user: Dilemel an implijer-mañ
       confirm: Kadarnaat
       friends_changesets: Strolladoù kemmoù graet gant mignoned
       friends_diaries: Enmonedoù deizlevr ar vignoned
@@ -2079,6 +2083,8 @@ br:
       invalid_scope: Astenn dianav
     auth_association:
       heading: N'eo ket kevredet ho ID ouzh ur gont OpenStreetMap.
+      option_1: Ma'z oc'h un den nevez en OpenStreetMap, krouit ur gont nevez, mar
+        plij, war-bouez ar furmskrid amañ dindan.
   user_role:
     filter:
       not_an_administrator: N'eus nemet ar verourien a c'hall merañ ar rolloù, ha
@@ -2260,6 +2266,8 @@ br:
       center_marker: Kreizañ ar gartenn war ar merker
       paste_html: Pegañ HTML evit bezañ enkorfet en ul lec'hienn web
       view_larger_map: Gwelet ur gartenn vrasoc'h
+    embed:
+      report_problem: Menegiñ ur gudenn
     key:
       title: Alc'hwez ar gartenn
       tooltip: Alc'hwez ar gartenn
@@ -2275,7 +2283,6 @@ br:
         standard: Standard
         cycle_map: Kelc'hiad kartenn
         transport_map: Kartenn treuzdougen
-        mapquest: MapQuest digor
         hot: Denegour
       layers:
         header: Gwiskadoù kartenn
index 6bc9fc1cac7fa908952166cb83ccfca73f5b791b..a984943dfa36879c6abf8e58b0b2a068ab3953dd 100644 (file)
@@ -15,6 +15,7 @@
 # Author: Macofe
 # Author: Martorell
 # Author: McDutchie
+# Author: Medol
 # Author: Micru
 # Author: Mlforcada
 # Author: Nemo bis
@@ -31,6 +32,8 @@
 # Author: 아라
 ---
 ca:
+  html:
+    dir: ltr
   time:
     formats:
       friendly: '%e %B %Y a les %H.%M'
@@ -1117,7 +1120,7 @@ ca:
       trademarks_title_html: <span id="trademarks"></span>Marques registrades
       trademarks_1_html: OpenStreetMap i el logotip de la lupa són marques registrades
         de la Fundació OpenStreetMap. Si teniu preguntes sobre l'ús de les marques,
-        si us plau envieu-les vostres al <a href="http://wiki.osmfoundation.org/wiki/Licensing_Working_Group">Grup
+        si us plau envieu les vostres al <a href="http://wiki.osmfoundation.org/wiki/Licensing_Working_Group">Grup
         de Treball de Llicències</a>.
   welcome_page:
     title: Benvingut!
@@ -1501,6 +1504,9 @@ ca:
           track: Pista
           bridleway: Camí de ferradura
           cycleway: Carril bici
+          cycleway_national: Via ciclista nacional
+          cycleway_regional: Via ciclista regional
+          cycleway_local: Via ciclista local
           footway: Footway
           rail: Ferrocarril
           subway: Metro
@@ -1553,6 +1559,9 @@ ca:
           private: Accés privat
           destination: Accés de destinació
           construction: Carreteres en construcció
+          bicycle_shop: Botiga de bicicletes
+          bicycle_parking: Aparcament de bicicleta
+          toilets: Lavabos
     richtext_area:
       edit: Modifica
       preview: Previsualització
@@ -1824,6 +1833,9 @@ ca:
         windowslive:
           title: Inici de sessió amb Windows Live
           alt: Inici de sessió amb un Compte de Windows Live
+        github:
+          title: Inicia la sessió amb GitHub
+          alt: Inicia la sessió amb un compte de GitHub
         yahoo:
           title: Inicieu la sessió amb Yahoo
           alt: Inici de sessió amb un compte OpenID de Yahoo
@@ -2031,6 +2043,8 @@ ca:
         gravatar: Usa Gravatar
         link: http://wiki.openstreetmap.org/wiki/Gravatar
         link text: què és això?
+        disabled: S'ha inhabilitat Gravatar.
+        enabled: S'ha habilitat que es mostri el vostre Gravatar.
       new image: Afegeix una imatge
       keep image: Conserva la imatge actual
       delete image: Suprimeix la imatge actual
@@ -2331,7 +2345,6 @@ ca:
         standard: Estàndard
         cycle_map: Cycle Map
         transport_map: Mapa de transports
-        mapquest: MapQuest Open
         hot: Humanitarian
       layers:
         header: Capes del mapa
index 201bc743006bafb11fd0e36fae917330f9163826..465dab9cb00310d5067b42730e56c5f9feff1bdb 100644 (file)
@@ -5,12 +5,16 @@
 # Author: Chmee2
 # Author: Cvanca
 # Author: DemonioCZ
+# Author: Dvorapa
 # Author: H4nek
 # Author: JAn Dudík
 # Author: Jezevec
 # Author: Jkjk
 # Author: Kuvaly
 # Author: Luk
+# Author: LukasJandera
+# Author: Marek Pavlica
+# Author: Martin Urbanec
 # Author: Masox
 # Author: Matěj Grabovský
 # Author: Michaelbrabec
@@ -23,6 +27,7 @@
 # Author: Tchoř
 # Author: Urbanecm
 # Author: Veritaslibero
+# Author: Walter Klosse
 ---
 cs:
   time:
@@ -50,14 +55,14 @@ cs:
       old_relation_tag: Tag staré relace
       old_way: Stará cesta
       old_way_node: Uzel staré cesty
-      old_way_tag: Starý tag cesty
+      old_way_tag: Starý způsob tagu
       relation: Relace
       relation_member: Člen relace
       relation_tag: Tag relace
       session: Relace
       trace: Stopa
       tracepoint: Bod stopy
-      tracetag: Štítek stopy
+      tracetag: Tag stopy
       user: Uživatel
       user_preference: Uživatelské nastavení
       user_token: Uživatelský token
@@ -116,12 +121,14 @@ cs:
     closed: Uzavřeno
     created_html: Vytvořeno <abbr title='%{title}'>před %{time}</abbr>
     closed_html: Uzavřeno <abbr title='%{title}'>před %{time}</abbr>
-    created_by_html: Vytvořil <abbr title='%{title}'>před %{time}</abbr> %{user}
+    created_by_html: Vytvořeno <abbr title='%{title}'>před %{time}</abbr> uživatelem
+      %{user}
     deleted_by_html: Smazáno <abbr title='%{title}'>před %{time}</abbr> uživatelem
       %{user}
     edited_by_html: Upraveno <abbr title='%{title}'>před %{time}</abbr> uživatelem
       %{user}
-    closed_by_html: Uzavřel <abbr title='%{title}'>před %{time}</abbr> uživatel %{user}
+    closed_by_html: Uzavřeno <abbr title='%{title}'>před %{time}</abbr> uživatelem
+      %{user}
     version: Verze
     in_changeset: Sada změn
     anonymous: anonym
@@ -141,15 +148,15 @@ cs:
       relation: Relace (%{count})
       relation_paginated: Relace (%{x}–%{y} z %{count})
       comment: Komentáře (%{count})
-      hidden_commented_by: Skrytý komentář od %{user} <abbr title='%{exact_time}'>Před
+      hidden_commented_by: Skrytý komentář od uživatele %{user} <abbr title='%{exact_time}'>před
         %{when}</abbr>
       commented_by: <abbr title='%{exact_time}'>Před %{when}</abbr> okomentoval %{user}
-      changesetxml: Soubor změn XML
+      changesetxml: Sada změn XML
       osmchangexml: osmChange XML
       feed:
         title: Sada změn %{id}
-        title_comment: 'Sada změn: %{id} - %{comment}'
-      join_discussion: Pokud chcete diskutovat, přihlaste se
+        title_comment: Sada změn %{id} - %{comment}
+      join_discussion: Chcete-li diskutovat, přihlaste se
       discussion: Diskuse
     node:
       title: 'Uzel: %{name}'
@@ -220,19 +227,22 @@ cs:
       hidden_title: 'Skrytá poznámka #%{note_name}'
       open_by: Vytvořil %{user} <abbr title='%{exact_time}'>před %{when}</abbr>
       open_by_anonymous: Vytvořil anonym <abbr title='%{exact_time}'>před %{when}</abbr>
-      commented_by: <abbr title='%{exact_time}'>Před %{when}</abbr> okomentoval %{user}
+      commented_by: <abbr title='%{exact_time}'>Před %{when}</abbr> okomentoval uživatel
+        %{user}
       commented_by_anonymous: <abbr title='%{exact_time}'>Před %{when}</abbr> okomentoval
         anonym
-      closed_by: Vyřešil <abbr title='%{exact_time}'>před %{when}</abbr> %{user}
+      closed_by: Vyřešil <abbr title='%{exact_time}'>před %{when}</abbr> uživatel
+        %{user}
       closed_by_anonymous: Vyřešil <abbr title='%{exact_time}'>před %{when}</abbr>
         anonym
-      reopened_by: Reaktivoval <abbr title='%{exact_time}'>před %{when}</abbr> %{user}
+      reopened_by: Reaktivoval <abbr title='%{exact_time}'>před %{when}</abbr> uživatel
+        %{user}
       reopened_by_anonymous: Reaktivoval <abbr title='%{exact_time}'>před %{when}</abbr>
         anonym
-      hidden_by: Skryl <abbr title='%{exact_time}'>před %{when}</abbr> %{user}
+      hidden_by: Skryl <abbr title='%{exact_time}'>před %{when}</abbr> uživatel %{user}
     query:
       title: Průzkum prvků
-      introduction: Pro nalezení okolních prvků klikněte do mapy.
+      introduction: Pro nalezení okolních prvků klikněte na mapu.
       nearby: Okolní prvky
       enclosing: Umístění prvku
   changeset:
@@ -259,7 +269,7 @@ cs:
       empty_area: Pro tuto oblast neexistují žádné sady změn.
       empty_user: Tento uživatel nemá žádné sady změn.
       no_more: Nebyly nalezeny žádné další sady změn.
-      no_more_area: Nebyly nalezeny žádné další sady změn pro tuto oblast.
+      no_more_area: Pro tuto oblast nebyly nalezeny žádné další sady změn.
       no_more_user: Nebyly nalezeny žádné další sady změn tohoto uživatele.
       load_more: Načíst další
     timeout:
@@ -284,7 +294,7 @@ cs:
       new: Nový záznam do deníčku
       new_title: Vložit nový záznam do vašeho uživatelského deníčku
       no_entries: Žádné záznamy v deníčku
-      recent_entries: Aktuální deníčkové záznamy
+      recent_entries: Nedávné deníčkové záznamy
       older_entries: Starší záznamy
       newer_entries: Novější záznamy
     edit:
@@ -336,7 +346,7 @@ cs:
         description: Nedávné záznamy v OpenStreetMap deníčku uživatele %{user}
       language:
         title: Deníčkové záznamy OpenStreetMap v jazyce %{language_name}
-        description: Aktuální záznamy v deníčcích uživatelů OpenStreetMap v jazyce
+        description: Nedávné záznamy v deníčcích uživatelů OpenStreetMap v jazyce
           %{language_name}
       all:
         title: Deníčkové záznamy OpenStreetMap
@@ -365,7 +375,7 @@ cs:
         advice: 'Pokud se tento export nezdaří, zvažte použití jednoho z následujících
           zdrojů:'
         body: 'Tato oblast je pro export do XML formátu OpenStreetMap příliš velká.
-          Přejděte na větší měřítko, zvolte menší oblast nebo použijte jeden z následujících
+          Přejděte na větší měřítko, zvolte menší oblast, nebo použijte jeden z následujících
           zdrojů pro stahování velkého množství dat:'
         planet:
           title: Planeta OSM
@@ -567,7 +577,7 @@ cs:
           motorway: Dálnice
           motorway_junction: Dálniční křižovatka
           motorway_link: Dálnice
-          path: Pěšina
+          path: Stezka
           pedestrian: Pěší zóna
           platform: Nástupiště
           primary: Silnice první třídy
@@ -576,7 +586,7 @@ cs:
           raceway: Závodní dráha
           residential: Ulice
           rest_area: Odpočívadlo
-          road: Cesta
+          road: Silnice
           secondary: Silnice druhé třídy
           secondary_link: Silnice druhé třídy
           service: Účelová komunikace
@@ -1082,9 +1092,9 @@ cs:
         pro odstranění</a> nebo přímo podejte výzvu pomocí <a href="http://dmca.openstreetmap.org/">on-line
         formuláře</a>.
       trademarks_title_html: <span id="trademarks"></span>Ochranné známky
-      trademarks_1_html: OpenStreetMap a logo s lupou jsou zapsané ochranné známky
-        OpenStreetMap Foundation. Pokud máte dotazy ohledně vašeho používání těchto
-        známek, zašlete své dotazy <a href="http://wiki.osmfoundation.org/wiki/Licensing_Working_Group">pracovní
+      trademarks_1_html: OpenStreetMap, logo s lupou a State of the Map jsou zapsané
+        ochranné známky OpenStreetMap Foundation. Pokud máte dotazy ohledně vašeho
+        používání těchto známek, zašlete své dotazy <a href="http://wiki.osmfoundation.org/wiki/Licensing_Working_Group">pracovní
         skupině pro licencování</a>.
   welcome_page:
     title: Vítejte!
@@ -1461,6 +1471,9 @@ cs:
           track: Lesní a polní cesta
           bridleway: Koňská stezka
           cycleway: Cyklostezka
+          cycleway_national: Národní cyklotrasa
+          cycleway_regional: Regionální cyklotrasa
+          cycleway_local: Místní cyklotrasa
           footway: Pěší cesta
           rail: Železnice
           subway: Metro
@@ -1513,6 +1526,9 @@ cs:
           private: Soukromý pozemek
           destination: Průjezd zakázán
           construction: Cesta ve výstavbě
+          bicycle_shop: Cykloobchod
+          bicycle_parking: Parkoviště pro kola
+          toilets: Záchody
     richtext_area:
       edit: Upravit
       preview: Náhled
@@ -1787,6 +1803,9 @@ cs:
         windowslive:
           title: Přihlásit se přes Windows Live
           alt: Přihlášení pomocí účtu služeb Windows Live
+        github:
+          title: Přihlásit se přes GitHub
+          alt: Přihlásit se pomocí GitHub účtu
         yahoo:
           title: Přihlásit se prostřednictvím Yahoo
           alt: Přihlášení pomocí Yahoo OpenID
@@ -1992,6 +2011,8 @@ cs:
         gravatar: Používat Gravatar
         link: http://wiki.openstreetmap.org/wiki/CS:Gravatar
         link text: co to znamená?
+        disabled: Gravatar byl zakázán.
+        enabled: Zobrazování vašeho Gravataru bylo povoleno.
       new image: Přidat obrázek
       keep image: Zachovat stávající obrázek
       delete image: Odstranit stávající obrázek
@@ -2281,7 +2302,6 @@ cs:
         standard: Standardní
         cycle_map: Cyklomapa
         transport_map: Dopravní mapa
-        mapquest: MapQuest Open
         hot: Humanitární
       layers:
         header: Mapové vrstvy
@@ -2343,11 +2363,21 @@ cs:
       instructions:
         continue_without_exit: Pokračujte na %{name}
         slight_right_without_exit: Mírně vpravo na %{name}
+        offramp_right_without_exit: Použijte nájezd vpravo na %{name}
+        onramp_right_without_exit: Odbočte vpravo na nájezd na %{name}
+        endofroad_right_without_exit: Na konci silnice odbočte vpravo na %{name}
+        merge_right_without_exit: Připojte se vpravo na %{name}
+        fork_right_without_exit: Na rozcestí odbočte vpravo na %{name}
         turn_right_without_exit: Odbočte vpravo na %{name}
         sharp_right_without_exit: Ostře vpravo na %{name}
         uturn_without_exit: Otočte se na %{name}
         sharp_left_without_exit: Ostře vlevo na %{name}
         turn_left_without_exit: Odbočte vlevo na %{name}
+        offramp_left_without_exit: Použijte nájezd vlevo na %{name}
+        onramp_left_without_exit: Odbočte vlevo na nájezd na %{name}
+        endofroad_left_without_exit: Na konci silnice odbočte vlevo na %{name}
+        merge_left_without_exit: Připojte se vlevo na %{name}
+        fork_left_without_exit: Na rozcestí odbočte vlevo na %{name}
         slight_left_without_exit: Mírně vlevo na %{name}
         via_point_without_exit: (zastávka)
         follow_without_exit: Jeďte po %{name}
index 07a9616cf5a1c4ac6725ccd41935102392719fe4..7fc38de1ffea0e48e793d80e19ce452f634dda2c 100644 (file)
@@ -1546,6 +1546,8 @@ da:
           private: Privat adgang
           destination: Ærindekørsel tilladt
           construction: Veje under konstruktion
+          bicycle_parking: Cykelparkering
+          toilets: Toiletter
     richtext_area:
       edit: Redigér
       preview: Forhåndsvisning
index eb3f243126ffd0e4bcf964ae1078e36f2c0b13c7..713a13c9feacaf584b926e94ef1f59c31b65345a 100644 (file)
@@ -45,6 +45,7 @@
 # Author: Suriyaa Kudo
 # Author: Tehabe
 # Author: The Evil IP address
+# Author: ThePiscin
 # Author: Thomas Bohn
 # Author: Umherirrender
 # Author: Woodpeck
@@ -633,7 +634,7 @@ de:
           city_gate: Stadttor
           citywalls: Stadtmauern
           fort: Fort
-          heritage: Denkmalschutz
+          heritage: Denkmalgeschützt
           house: Historisches Haus
           icon: Symbol
           manor: Gutshaus
@@ -731,7 +732,7 @@ de:
           cliff: Klippe
           crater: Krater
           dune: Düne
-          fell: Weide
+          fell: Fjell
           fjord: Fjord
           forest: Wald
           geyser: Geysir
@@ -806,11 +807,11 @@ de:
           "yes": Ort
         railway:
           abandoned: Aufgegebene Bahnstrecke
-          construction: Eisenbahn im Bau
+          construction: Bahnstrecke im Bau
           disused: Aufgelassene Bahnstrecke
           disused_station: Aufgelassener Bahnhof
           funicular: Standseilbahn
-          halt: Haltepunkt
+          halt: Haltestelle
           historic_station: Historischer Bahnhof
           junction: Bahnknoten