exvo_globalize 0.5.4 → 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,41 @@
1
+ /**
2
+ * jQuery Cookie plugin
3
+ *
4
+ * Copyright (c) 2010 Klaus Hartl (stilbuero.de)
5
+ * Dual licensed under the MIT and GPL licenses:
6
+ * http://www.opensource.org/licenses/mit-license.php
7
+ * http://www.gnu.org/licenses/gpl.html
8
+ *
9
+ */
10
+ var cookie = function (key, value, options) {
11
+
12
+ // key and at least value given, set cookie...
13
+ if (arguments.length > 1 && String(value) !== "[object Object]") {
14
+ options = jQuery.extend({}, options);
15
+
16
+ if (value === null || value === undefined) {
17
+ options.expires = -1;
18
+ }
19
+
20
+ if (typeof options.expires === 'number') {
21
+ var days = options.expires, t = options.expires = new Date();
22
+ t.setDate(t.getDate() + days);
23
+ }
24
+
25
+ value = String(value);
26
+
27
+ return (document.cookie = [
28
+ encodeURIComponent(key), '=',
29
+ options.raw ? value : encodeURIComponent(value),
30
+ options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
31
+ options.path ? '; path=' + options.path : '',
32
+ options.domain ? '; domain=' + options.domain : '',
33
+ options.secure ? '; secure' : ''
34
+ ].join(''));
35
+ }
36
+
37
+ // key and possibly options given, get cookie...
38
+ options = value || {};
39
+ var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent;
40
+ return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null;
41
+ };
@@ -0,0 +1,67 @@
1
+ $themes_url: "http://themes.exvo.com/"
2
+
3
+ .layout
4
+ color: #1f2b3f
5
+
6
+ .pane.content > .pane
7
+ border: none
8
+ .row, .bar
9
+ .cell
10
+ min-height: 1px
11
+ &.left
12
+ float: left
13
+
14
+ &.center
15
+ h1
16
+ text-align: center
17
+ .bar
18
+ h1.black
19
+ color: #000
20
+
21
+ table
22
+ table-layout: auto
23
+ tr
24
+ td
25
+ form, .button, button
26
+ float: left
27
+ margin-left: 5px
28
+ &:nth-child(odd) td
29
+ background-color: rgba(0, 44, 132, 0.11)
30
+
31
+ .tool
32
+ .cell
33
+ height: 50px
34
+ &.last
35
+ text-align: right
36
+
37
+ .layout
38
+ .bar
39
+ h1
40
+ color: #1f2b3f
41
+ a
42
+ color: #1f2b3f
43
+ text-decoration: none
44
+
45
+ &.button
46
+ color: black
47
+
48
+ &.sup
49
+ line-height: 38px
50
+
51
+ sup
52
+ vertical-align: super
53
+ color: #3b4b5a
54
+ font-size: 12px
55
+ margin-left: 5px
56
+
57
+ label
58
+ display: inline-block
59
+ margin-left: 10px
60
+
61
+ #pagination
62
+ background-color: #dfe5eb
63
+ background-image: url(/images/apps/toolbar_bg.png)
64
+ background-repeat: repeat-x
65
+ border-top: 0.1em solid #8a9096
66
+ padding: 5px
67
+ text-align: center
@@ -0,0 +1,51 @@
1
+ $themes_url: "http://themes.exvo.com/"
2
+
3
+ .layout
4
+ #sidebar, .side.pane.left
5
+ background:
6
+ image: url("/images/common/shadow/top.png")
7
+ repeat: repeat-x
8
+ position: left top
9
+
10
+ .row .cell.last_child
11
+ float: right
12
+
13
+ .bar .cell
14
+ &.last_child, &.right
15
+ float: right
16
+ padding-right: 10px
17
+
18
+ table
19
+ tr
20
+ td
21
+ .button, button
22
+ min-width: 46px
23
+
24
+ .switch
25
+ .button, button
26
+ min-width: 1px
27
+
28
+ .layout .viewport
29
+ .pane, .pane.left, .pane.side.left.side_menu.shadow
30
+ background:
31
+ image: url(#{$themes_url}stylesheets/images/common/shadow/top.png)
32
+ position: top left
33
+ repeat: repeat-x
34
+ size: 1px 7px
35
+
36
+ .pane.side.left.side_menu.shadow_right
37
+ background:
38
+ image: url(#{$themes_url}stylesheets/images/common/shadow/right.png)
39
+ position: top right
40
+ repeat: repeat-y
41
+ size: 7px 1px
42
+
43
+
44
+
45
+ .slides_container.pane.white.shadow_bottom, .website.show>.title, .layout .bar.linen_white.shadow_bottom, .website_settings.top.pane.static, .linen_white.shadow_top
46
+ background:
47
+ color: transparent
48
+ image: url(/images/common/linen_w.png)
49
+ position: 0 0
50
+ repeat: repeat
51
+ size: 500px 500px
@@ -0,0 +1,51 @@
1
+ class GlobalizeTranslationSuggestionsController < ApplicationController
2
+ before_filter :find_suggestion, :except => :feedback
3
+
4
+ def send_feedback
5
+ if @translation_suggestion
6
+ @translation_suggestion.increment!(:votes)
7
+ else
8
+ suggestion = @globalize_translation.globalize_translation_suggestions.build(:value => params[:body])
9
+
10
+ if !suggestion.save
11
+ render :json => { :errors => suggestion.errors.full_messages }, :format => "json", :status => :unprocessable_entity
12
+ return
13
+ end
14
+ end
15
+
16
+ render :nothing => true, :status => :ok
17
+ end
18
+
19
+ def feedback
20
+ @current_locale = params[:locale].blank? ? I18n.default_locale : params[:locale]
21
+
22
+ @translations = GlobalizeTranslation.includes(:globalize_translation_suggestions).
23
+ where(:locale => @current_locale).
24
+ order(:key)
25
+
26
+ unless params[:query].blank?
27
+ @translations = @translations.where("value like ?", "%#{params[:query]}%")
28
+ end
29
+
30
+ @translations = @translations.offset(params[:page].to_i * 20).limit(40).all
31
+
32
+ if request.xhr?
33
+ render :partial => "globalize_translation", :collection => @translations
34
+ else
35
+ render :layout => 'globalize_feedback'
36
+ end
37
+ end
38
+
39
+ private
40
+ def find_suggestion
41
+ @globalize_translation = GlobalizeTranslation.find(params[:globalize_translation_id])
42
+
43
+ if @globalize_translation
44
+ if !params[:body].blank?
45
+ @translation_suggestion = @globalize_translation.globalize_translation_suggestions.where(:value => params[:body]).first
46
+ elsif !params[:globalize_translation_suggestion_id].blank?
47
+ @translation_suggestion = @globalize_translation.globalize_translation_suggestions.find(params[:globalize_translation_suggestion_id])
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,5 @@
1
+ module GlobalizeHelper
2
+ def link_to_globalize_feedback(text = "Send Feedback", locale = I18n.default_locale)
3
+ link_to text, feedback_globalize_translations_path(:locale => locale)
4
+ end
5
+ end
@@ -1,4 +1,5 @@
1
1
  class GlobalizeTranslation < ActiveRecord::Base
2
+ has_many :globalize_translation_suggestions
2
3
 
3
4
  # based on https://github.com/svenfuchs/i18n-active_record/blob/master/lib/i18n/backend/active_record/translation.rb
4
5
 
@@ -15,4 +16,33 @@ class GlobalizeTranslation < ActiveRecord::Base
15
16
  find(:all, :select => 'DISTINCT locale').map { |t| t.locale.to_sym }
16
17
  end
17
18
 
18
- end
19
+ def last_key
20
+ key.split(".").last
21
+ end
22
+
23
+ # based on doc/pluralization_analysis which was written while analysing
24
+ # http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
25
+ #
26
+ # key - one of 'zero', 'one', 'two', 'few', 'many', 'other'
27
+ def self.is_interpolation_mandatory?(language_code, key)
28
+ rule = I18n.t(:'i18n.plural.rule', :locale => language_code.to_sym, :resolve => false)
29
+ key = key.to_sym
30
+ case key
31
+ when :zero
32
+ return false
33
+ when :one
34
+ return rule.call(0) == :one || rule.call(21) == :one
35
+ when :two
36
+ return rule.call(102) == :two
37
+ when :few
38
+ return rule.call(4) == :few
39
+ when :many
40
+ return rule.call(6) != :many || rule.call(11) == :many
41
+ when :other
42
+ return true
43
+ else
44
+ raise "unexpected key: #{key}"
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,29 @@
1
+ class GlobalizeTranslationSuggestion < ActiveRecord::Base
2
+ belongs_to :globalize_translation
3
+
4
+ validates :value, :presence => true
5
+ validate :interpolations_required?
6
+
7
+ after_update :update_suggestion, :if => :votes_changed?
8
+
9
+ def interpolations_required?
10
+ original_text = self.globalize_translation.value
11
+
12
+ interpolations = original_text.scan(/%?\{.+?\}/)
13
+ unless interpolations.empty?
14
+ translations_interpolation = extract_interpolations(translation)
15
+
16
+ if interpolations.sort != translations_interpolation.sort
17
+ errors.add :interpolations, "Translation should include all interpolation elements: #{interpolations.join(", ")}"
18
+ end
19
+ end
20
+ end
21
+
22
+ private
23
+ # Updates the original phrase with the suggestion gave by users when the number of votes is met.
24
+ def update_suggestion
25
+ if (self.votes + 1) > ExvoGlobalize.feedback_votes_count
26
+ self.globalize_translation.update_attributes(:value => self.value)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,33 @@
1
+ %tr
2
+ %td
3
+ = globalize_translation.key
4
+ %td
5
+ = globalize_translation.value
6
+ %td
7
+ = t(globalize_translation.key)
8
+ %td
9
+ = select_tag "suggestions", options_from_collection_for_select(globalize_translation.globalize_translation_suggestions, "id", "value"), :style => "width: 100%", :prompt => "Select one", :class => "suggestion_options"
10
+ %td
11
+ - if I18n.t(:'i18n.plural.keys', :locale => globalize_translation.locale, :resolve => false).include?(globalize_translation.last_key.to_sym)
12
+ %span.bold
13
+ = t('feedback.plural_forms')
14
+ %br
15
+ %br
16
+ = t('feedback.different_pluralization_rules').html_safe
17
+ = t('feedback.different_pluralization_forms').html_safe
18
+ %br
19
+ %br
20
+ = t('feedback.your_job_is_to_translate', :original_phrase => t(globalize_translation.key), :language => globalize_translation.locale).html_safe
21
+ %br
22
+
23
+ = t('feedback.enter_the_correct_pluralization').html_safe
24
+ %span.bold :#{globalize_translation.last_key}
25
+
26
+ - if ExvoGlobalize::Plurals::HINTS[globalize_translation.locale]
27
+ = "(i.e. '#{ExvoGlobalize::Plurals::PLURAL_RULES[globalize_translation.locale][globalize_translation.last_key]} #{ExvoGlobalize::Plurals::HINTS[globalize_translation.locale][globalize_translation.last_key]}')"
28
+ - if GlobalizeTranslation.is_interpolation_mandatory?(globalize_translation.locale, globalize_translation.last_key)
29
+ = t('feedback.interpolation_example', :example => ExvoGlobalize::Plurals::HINTS[globalize_translation.locale][globalize_translation.last_key]).html_safe
30
+
31
+ %input{:type => "text", :style => "width: 100%", :class => "suggestion"}
32
+ %td
33
+ %button{:"globalize-translation-id" => globalize_translation.id, :class => "send_feedback"} Send Feedback
@@ -0,0 +1,11 @@
1
+ %div
2
+ .pane.static
3
+ %table.feedback
4
+ %tr
5
+ %th{:style => "width: 15%"} Path
6
+ %th{:style => "width: 20%"} Translation
7
+ %th{:style => "width: 20%"} Original
8
+ %th{:style => "width: 15%"} Suggestions
9
+ %th{:style => "width: 20%"} Your Suggestion
10
+ %th{:style => "width: 10%"} &nbsp;
11
+ = render :partial => "globalize_translation", :collection => @translations
@@ -0,0 +1,49 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %title Exvo Globalize
5
+
6
+ %meta{ :'http-equiv' => "content-type", :content => "text/html; charset=utf-8" }
7
+ = csrf_meta_tags
8
+
9
+ %link{ :href => "/favicon.ico", :rel => "shortcut icon", :type => "image/x-icon" }
10
+ - prefix = Rails.env == "production" ? '' : 'staging.'
11
+ = stylesheet_link_tag "http://themes.exvo.com/stylesheets/themes/ice/all.css", :reload => false
12
+ = stylesheet_link_tag "http://themes.exvo.com/stylesheets/themes/ice/layout.css", :reload => false
13
+ = stylesheet_link_tag "exvo_globalize"
14
+ /[if IE 8]
15
+ = stylesheet_link_tag "ie"
16
+
17
+ %script{ :type => "text/javascript", :src => "http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js", :charset => "utf-8" }
18
+ %script{ :type => "text/javascript", :src => "http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.3/jquery-ui.min.js", :charset => "utf-8" }
19
+ %script{ :src => "http://#{ prefix }cdn.exvo.com/javascripts/utils.js", :type => "text/javascript" }
20
+ %script{ :src => "http://#{ prefix }cdn.exvo.com/javascripts/widgets.js", :type => "text/javascript" }
21
+ %script{ :src => "http://#{ prefix }cdn.exvo.com/javascripts/plugins.js", :type => "text/javascript" }
22
+
23
+ = javascript_include_tag "jquery.cookie"
24
+ = javascript_include_tag "exvo_feedback"
25
+ = javascript_include_tag "exvo_rails_ujs"
26
+ %body
27
+ .layout
28
+ .tool.bar
29
+ .cell.left
30
+ %h1
31
+ %a{ :href => "http://globalize.exvo.com", :class => "sup" }
32
+ #{ image_tag("http://themes.exvo.com/stylesheets/images/icons/apps/globalize32.png") } #{"Globalize Translation Studio" } <sup>BETA</sup>
33
+ %a{:href => "/", :class => "pages preview button back"} Back
34
+ .cell.right
35
+ %form{:method => "get"}
36
+ %input{:type => "text", :id => "search_body", :name => "query", :size => 40}
37
+ %input{:type => "hidden", :id => "locale", :name => "locale", :value => @current_locale}
38
+ %button{:id => "search_buttom"} Search
39
+ .viewport
40
+ .content.pane
41
+ = render 'globalize_translations/flash_messages'
42
+ = yield
43
+ .bottom.bar.fat
44
+ .cell.third
45
+ = yield :first_in_bottom
46
+ .cell.third.center
47
+ = yield :second_in_bottom
48
+ .cell.third.right
49
+ = yield :third_in_bottom
@@ -220,3 +220,11 @@ en:
220
220
 
221
221
  full_messages:
222
222
  format: "%{attribute} %{message}"
223
+
224
+ feedback:
225
+ plural_forms: 'PLURAL FORMS'
226
+ different_pluralization_rules: 'Different languages have different <strong><a href="http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html" target="_blank">pluralization rules</a></strong>.'
227
+ different_pluralization_forms: 'For each language there is usually more than one pluralization form. Each form is identified by the key (:zero, :one, :two, :few, :many, :other). Not all keys are used in all languages (sometimes there is only one key being used).'
228
+ your_job_is_to_translate: 'Your job is to translate the phrase "<strong>%{original_phrase}</strong>" into different plural forms into the <strong>%{language}</strong> language.'
229
+ enter_the_correct_pluralization: 'Please enter the correct pluralization form for'
230
+ interpolation_example: ', but use the &#37;{count} interpolation in the phrase, so the correct key looks similar to this: &#37;{count} %{example}'
data/config/routes.rb CHANGED
@@ -3,6 +3,8 @@ Rails.application.routes.draw do
3
3
  resource :translations, :only => [:show, :update], :as => 'globalize_translations', :controller => 'globalize_translations' do
4
4
  resources :js, :only => [:show], :as => 'javascript', :controller => 'globalize_translations'
5
5
  get :list
6
+ get :feedback, :controller => "globalize_translation_suggestions"
7
+ match 'send_feedback/:globalize_translation_id', :to => "globalize_translation_suggestions#send_feedback", :as => :send_feedback
6
8
  end
7
9
  end
8
10
  end
@@ -6,6 +6,7 @@ require "exvo_globalize/backend/globalize_store"
6
6
  require "exvo_globalize/backend/simple"
7
7
  require 'exvo_globalize/globalize_app'
8
8
  require 'exvo_globalize/helpers'
9
+ require 'exvo_globalize/plural_examples'
9
10
  require 'haml'
10
11
  require 'httparty'
11
12
  require 'awesome_print'
@@ -14,4 +15,12 @@ require 'ya2yaml'
14
15
  # Make it a Rails engine
15
16
  module ExvoGlobalize
16
17
  require 'exvo_globalize/engine' if defined?(Rails)
17
- end
18
+
19
+ def self.feedback_votes_count
20
+ @feedback_votes_count || 40
21
+ end
22
+
23
+ def self.feedback_votes_count=(value)
24
+ @feedback_votes_count = value
25
+ end
26
+ end
@@ -0,0 +1,878 @@
1
+ # encoding: utf-8
2
+ require 'active_support/core_ext/hash/indifferent_access'
3
+
4
+ module ExvoGlobalize
5
+ module Plurals
6
+ # https://github.com/svenfuchs/i18n/blob/master/test/test_data/locales/plurals.rb
7
+
8
+ PLURAL_RULES = HashWithIndifferentAccess.new({
9
+ :af => { # africaans
10
+ :one => 1,
11
+ :other => 2
12
+ },
13
+
14
+ :ar => { # arabic
15
+ :zero => 0,
16
+ :one => 1,
17
+ :two => 2,
18
+ :few => 3,
19
+ :many => 11,
20
+ :other => 100
21
+ },
22
+
23
+ :az => { # Azerbaijani
24
+ :other => 3
25
+ },
26
+
27
+ :be => { # Belarusian
28
+ :one => 1,
29
+ :few => 2,
30
+ :many => 7,
31
+ :other => 10.2
32
+ },
33
+
34
+ :bg => { # Bulgarian
35
+ :one => 1,
36
+ :other => 5
37
+ },
38
+
39
+ :bn => { # Bengali
40
+ :one => 1,
41
+ :other => 5
42
+ },
43
+
44
+ :ca => { # Catalan
45
+ :one => 1,
46
+ :other => 5
47
+ },
48
+
49
+ :cs => { # Czech
50
+ :one => 1,
51
+ :few => 2,
52
+ :other => 5
53
+ },
54
+
55
+ :cy => { # Welsch # 1 tree.
56
+ :one => 1,
57
+ :two => 2,
58
+ :many => 5,
59
+ :other => 15
60
+ },
61
+
62
+ :da => {
63
+ :one => 1,
64
+ :other => 2
65
+ },
66
+
67
+ :de => {
68
+ :one => 1,
69
+ :other => 2
70
+ },
71
+
72
+ :el => { # Greek
73
+ :one => 1,
74
+ :other => 2
75
+ },
76
+
77
+ :en => { #English
78
+ :one => 1,
79
+ :other => 2
80
+ },
81
+
82
+ :es => { #Spanish
83
+ :one => 1,
84
+ :other => 2
85
+ },
86
+
87
+ :et => { # Estonian
88
+ :one => 1,
89
+ :other => 2
90
+ },
91
+
92
+ :eu => { # Basque
93
+ :one => 1,
94
+ :other => 2
95
+ },
96
+
97
+ :fa => { # Persian
98
+ :other => 2
99
+ },
100
+
101
+ :fi => { # Finnish
102
+ :one => 1,
103
+ :other => 2
104
+ },
105
+
106
+ :fil => { # Filipino
107
+ :one => 1,
108
+ :other => 2
109
+ },
110
+
111
+ :fr => {
112
+ :one => 1,
113
+ :other => 2
114
+ },
115
+
116
+ :ga => { # Irish
117
+ :one => 1,
118
+ :two => 2,
119
+ :other => 5
120
+ },
121
+
122
+ :gl => { # Galician
123
+ :one => 1,
124
+ :other => 2
125
+ },
126
+
127
+ :gu => { # Gujarati
128
+ :one => 1,
129
+ :other => 2
130
+ },
131
+
132
+ :he => { # Hebrew
133
+ :one => 1,
134
+ :other => 2
135
+ },
136
+
137
+ :hi => { # Hindi
138
+ :one => 1,
139
+ :other => 2
140
+ },
141
+
142
+ :hr => { # Croatian
143
+ :one => 1,
144
+ :few => 2,
145
+ :many => 5,
146
+ :other => 10
147
+ },
148
+
149
+ :hu => { # Hungarian
150
+ :other => 2
151
+ },
152
+
153
+ :id => { # Indonesian
154
+ :other => 2
155
+ },
156
+
157
+ :is => { # Icelandic
158
+ :one => 1,
159
+ :other => 2
160
+ },
161
+
162
+ :it => { # Italian
163
+ :one => 1,
164
+ :other => 2
165
+ },
166
+
167
+ :ja => { # Japanese
168
+ :other => 2
169
+ },
170
+
171
+ :ka => { # Georgian
172
+ :other => 2
173
+ },
174
+
175
+ :kn => { # Kannada
176
+ :other => 2
177
+ },
178
+
179
+ :ko => { # Korean
180
+ :other => 2
181
+ },
182
+
183
+ :lt => { # Lithuanian
184
+ :one => 1,
185
+ :few => 3,
186
+ :other => 22
187
+ },
188
+
189
+ :lv => { # Latvian
190
+ :zero => 0,
191
+ :one => 1,
192
+ :other => 3
193
+ },
194
+
195
+ :mk => { # Macedonian
196
+ :one => 1,
197
+ :other => 10
198
+ },
199
+
200
+ :ms => { # Malay
201
+ :other => 2
202
+ },
203
+
204
+ :nl => { # Dutch; Flemish
205
+ :one => 1,
206
+ :other => 2
207
+ },
208
+
209
+ :no => { # Norwegian
210
+ :one => 1,
211
+ :other => 2
212
+ },
213
+
214
+ :pl => {
215
+ :one => 1,
216
+ :few => 2,
217
+ :other => 5
218
+ },
219
+
220
+ :pt => { # Portuguese
221
+ :one => 1,
222
+ :other => 2
223
+ },
224
+
225
+ :"pt-PT" => { # Portuguese-Portugal
226
+ :one => 1,
227
+ :other => 2
228
+ },
229
+
230
+ :ro => { # Romanian; Moldavian; Moldovan
231
+ :one => 1,
232
+ :few => 2,
233
+ :other => 5
234
+ },
235
+
236
+ :ru => {
237
+ :one => 1,
238
+ :few => 2,
239
+ :many => 5,
240
+ :other => 10.5
241
+ },
242
+
243
+ :sk => { # Slovak
244
+ :one => 1,
245
+ :few => 2,
246
+ :other => 5
247
+ },
248
+
249
+ :sl => { # Slovenian
250
+ :one => 1,
251
+ :two => 2,
252
+ :many => 5,
253
+ :other => 20
254
+ },
255
+
256
+ :sq => { # Albanian
257
+ :one => 1,
258
+ :other => 2
259
+ },
260
+
261
+ :sr => { # Serbian
262
+ :one => 1,
263
+ :few => 2,
264
+ :many => 10,
265
+ :other => 1.2
266
+ },
267
+
268
+ :sv => { # Swedish
269
+ :one => 1,
270
+ :other => 2
271
+ },
272
+
273
+ :sw => { # Swahili ; 1 tree
274
+ :one => 1,
275
+ :other => 2
276
+ },
277
+
278
+ :ta => { # Tamil
279
+ :one => 1,
280
+ :other => 2
281
+ },
282
+
283
+ :te => { # Telugu
284
+ :one => 1,
285
+ :other => 2
286
+ },
287
+
288
+ :th => { # Thai
289
+ :other => 2
290
+ },
291
+
292
+ :tr => { # Turkish
293
+ :other => 2
294
+ },
295
+
296
+ :uk => {
297
+ :one => 1,
298
+ :few => 2,
299
+ :many => 5,
300
+ :other => 10
301
+ },
302
+
303
+ :ur => { # Urdu
304
+ :one => 1,
305
+ :other => 2
306
+ },
307
+
308
+ :vi => { # Vietnamese
309
+ :other => 2
310
+ },
311
+
312
+ :zh => { # Chinese
313
+ :other => 2
314
+ }
315
+ })
316
+
317
+ HINTS = HashWithIndifferentAccess.new({
318
+ :af => { # africaans
319
+ :one => "appel",
320
+ :other => "appels"
321
+ },
322
+
323
+ # :am => { # Amharic
324
+ # :one => "",
325
+ # :other => ""
326
+ # },
327
+
328
+ :ar => { # arabic
329
+ :zero => "لا التفاح",
330
+ :one => "تفاحة",
331
+ :two => "التفاح",
332
+ :few => "التفاح",
333
+ :many => "التفاح",
334
+ :other => "التفاح"
335
+ },
336
+
337
+ :az => { # Azerbaijani
338
+ :other => "alma"
339
+ },
340
+
341
+ :be => { # Belarusian
342
+ :one => "яблык",
343
+ :few => "яблыка",
344
+ :many => "яблыкаў",
345
+ :other => "яблыкаў"
346
+ },
347
+
348
+ :bg => { # Bulgarian
349
+ :one => "ябълка",
350
+ :other => "ябълки"
351
+ },
352
+
353
+ # :bh => { # Bihari languages
354
+ # :one => "",
355
+ # :other => ""
356
+ # },
357
+
358
+ :bn => { # Bengali
359
+ :one => "আপেল",
360
+ :other => "আপেল"
361
+ },
362
+
363
+ # :bo => { # Tibetan
364
+ # :other => ""
365
+ # },
366
+ #
367
+ # :bs => { # Bosnian
368
+ # :one => "",
369
+ # :few => "",
370
+ # :many => "",
371
+ # :other => ""
372
+ # },
373
+
374
+ :ca => { # Catalan
375
+ :one => "poma",
376
+ :other => "pomes"
377
+ },
378
+
379
+ :cs => { # Czech
380
+ :one => "jablko",
381
+ :few => "jablka",
382
+ :other => "jablek"
383
+ },
384
+
385
+ :cy => { # Welsch # tree.
386
+ :one => "goeden",
387
+ :two => "goeden",
388
+ :many => "coed",
389
+ :other => "o goed"
390
+ },
391
+
392
+ :da => {
393
+ :one => "æble",
394
+ :other => "æbler"
395
+ },
396
+
397
+ :de => {
398
+ :one => "Apfel",
399
+ :other => "Äpfel"
400
+ },
401
+
402
+ # :dz => { # Dzongkha
403
+ # :other => ""
404
+ # },
405
+
406
+ :el => { # Greek
407
+ :one => "μήλο",
408
+ :other => "μήλα"
409
+ },
410
+
411
+ :en => { #English
412
+ :one => "apple",
413
+ :other => "apples"
414
+ },
415
+
416
+ # :eo => { #Esperanto
417
+ # :one => "",
418
+ # :other => ""
419
+ # },
420
+
421
+ :es => { #Spanish
422
+ :one => "manzana",
423
+ :other => "manzanas"
424
+ },
425
+
426
+ :et => { # Estonian
427
+ :one => "õun",
428
+ :other => "õuna"
429
+ },
430
+
431
+ :eu => { # Basque
432
+ :one => "sagar",
433
+ :other => "sagarrak"
434
+ },
435
+
436
+ :fa => { # Persian
437
+ :other => "سیب"
438
+ },
439
+
440
+ :fi => { # Finnish
441
+ :one => "omena",
442
+ :other => "omenaa"
443
+ },
444
+
445
+ :fil => { # Filipino
446
+ :one => "mansanas",
447
+ :other => "mansanas"
448
+ },
449
+
450
+ # :fo => { # Faroese
451
+ # :one => "",
452
+ # :other => ""
453
+ # },
454
+
455
+ :fr => {
456
+ :one => "pomme",
457
+ :other => "pommes"
458
+ },
459
+
460
+ # :fur => { # Friulian
461
+ # :one => "",
462
+ # :other => ""
463
+ # },
464
+ #
465
+ # :fy => { # Western Frisian
466
+ # :one => "",
467
+ # :other => ""
468
+ # },
469
+
470
+ :ga => { # Irish
471
+ :one => "úll",
472
+ :two => "úlla",
473
+ :other => "úll"
474
+ },
475
+
476
+ :gl => { # Galician
477
+ :one => "mazá",
478
+ :other => "mazás"
479
+ },
480
+
481
+ :gu => { # Gujarati
482
+ :one => "સફરજન",
483
+ :other => "સફરજન"
484
+ },
485
+
486
+ # :guw => { # not found..
487
+ # :one => "",
488
+ # :other => ""
489
+ # },
490
+ #
491
+ # :ha => { # Hausa
492
+ # :one => "",
493
+ # :other => ""
494
+ # },
495
+
496
+ :he => { # Hebrew
497
+ :one => "תפוח",
498
+ :other => "תפוחים"
499
+ },
500
+
501
+ :hi => { # Hindi
502
+ :one => "सेब",
503
+ :other => "सेब"
504
+ },
505
+
506
+ :hr => { # Croatian
507
+ :one => "jabuka",
508
+ :few => "jabuke",
509
+ :many => "jabuka",
510
+ :other => "jabuke"
511
+ },
512
+
513
+ :hu => { # Hungarian
514
+ :other => "alma"
515
+ },
516
+
517
+ :id => { # Indonesian
518
+ :other => "apel"
519
+ },
520
+
521
+ :is => { # Icelandic
522
+ :one => "epli",
523
+ :other => "epli"
524
+ },
525
+
526
+ :it => { # Italian
527
+ :one => "mela",
528
+ :other => "mele"
529
+ },
530
+
531
+ # :iw => { # couldn't find
532
+ # :one => "",
533
+ # :other => ""
534
+ # },
535
+
536
+ :ja => { # Japanese
537
+ :other => "りんご"
538
+ },
539
+
540
+ # :jv => { # Javanese
541
+ # :other => ""
542
+ # },
543
+
544
+ :ka => { # Georgian
545
+ :other => "ვაშლი"
546
+ },
547
+
548
+ # :km => { # Central Khmer
549
+ # :other => ""
550
+ # },
551
+
552
+ :kn => { # Kannada
553
+ :other => "ಸೇಬು"
554
+ },
555
+
556
+ :ko => { # Korean
557
+ :other => "사과"
558
+ },
559
+
560
+ # :ku => { # Kurdish
561
+ # :one => "",
562
+ # :other => ""
563
+ # },
564
+ #
565
+ # :lb => { # Luxembourgish; Letzeburgesch
566
+ # :one => "",
567
+ # :other => ""
568
+ # },
569
+ #
570
+ # :ln => { # Lingala
571
+ # :one => "",
572
+ # :other => ""
573
+ # },
574
+
575
+ :lt => { # Lithuanian
576
+ :one => "obuolys",
577
+ :few => "obuoliai",
578
+ :other => "obuolių"
579
+ },
580
+
581
+ :lv => { # Latvian
582
+ :zero => "nav āboli",
583
+ :one => "ābols",
584
+ :other => "ābolu"
585
+ },
586
+
587
+ # :mg => { # Malagasy
588
+ # :one => "",
589
+ # :other => ""
590
+ # },
591
+
592
+ :mk => { # Macedonian
593
+ :one => "јаболко",
594
+ :other => "јаболки"
595
+ },
596
+
597
+ # :ml => { # Malayalam
598
+ # :one => "",
599
+ # :other => ""
600
+ # },
601
+ #
602
+ # :mn => { # Mongolian
603
+ # :one => "",
604
+ # :other => ""
605
+ # },
606
+ #
607
+ # :mo => { # Not found
608
+ # :one => "",
609
+ # :few => "",
610
+ # :other => ""
611
+ # },
612
+ #
613
+ # :mr => { # Marathi
614
+ # :one => "",
615
+ # :other => ""
616
+ # },
617
+
618
+ :ms => { # Malay
619
+ :other => "epal"
620
+ },
621
+
622
+ # :mt => { # Maltese
623
+ # :one => "",
624
+ # :few => "",
625
+ # :many => "",
626
+ # :other => ""
627
+ # },
628
+ #
629
+ # :my => { # Burmese
630
+ # :other => ""
631
+ # },
632
+ #
633
+ # :nah => { # Nahuatl languages
634
+ # :one => "",
635
+ # :other => ""
636
+ # },
637
+ #
638
+ # :nb => { # Bokmål, Norwegian; Norwegian Bokmål
639
+ # :one => "",
640
+ # :other => ""
641
+ # },
642
+ #
643
+ # :ne => { # Nepali
644
+ # :one => "",
645
+ # :other => ""
646
+ # },
647
+
648
+ :nl => { # Dutch; Flemish
649
+ :one => "appel",
650
+ :other => "appels"
651
+ },
652
+
653
+ # :nn => { # Norwegian Nynorsk; Nynorsk, Norwegian
654
+ # :one => "",
655
+ # :other => ""
656
+ # },
657
+
658
+ :no => { # Norwegian
659
+ :one => "eple",
660
+ :other => "epler"
661
+ },
662
+
663
+ # :nso => { # Pedi; Sepedi; Northern Sotho
664
+ # :one => "",
665
+ # :other => ""
666
+ # },
667
+ #
668
+ # :om => { # Oromo
669
+ # :one => "",
670
+ # :other => ""
671
+ # },
672
+ #
673
+ # :or => { # Oriya
674
+ # :one => "",
675
+ # :other => ""
676
+ # },
677
+ #
678
+ # :pa => {
679
+ # :one => "",
680
+ # :other => ""
681
+ # },
682
+ #
683
+ # :pap => {
684
+ # :one => "",
685
+ # :other => ""
686
+ # },
687
+
688
+ :pl => {
689
+ :one => "jabłko",
690
+ :few => "jabłka",
691
+ :other => "jabłek"
692
+ },
693
+
694
+ :ps => { # Pushto; Pashto
695
+ :one => "",
696
+ :other => ""
697
+ },
698
+
699
+ :pt => { # Portuguese
700
+ :one => "maça",
701
+ :other => "maças"
702
+ },
703
+
704
+ :"pt-PT" => { # Portuguese-Portugal
705
+ :one => "maça",
706
+ :other => "maças"
707
+ },
708
+
709
+ :ro => { # Romanian; Moldavian; Moldovan
710
+ :one => "mar",
711
+ :few => "mere",
712
+ :other => "mere"
713
+ },
714
+
715
+ :ru => {
716
+ :one => "яблоко",
717
+ :few => "яблока",
718
+ :many => "яблок",
719
+ :other => "яблок"
720
+ },
721
+
722
+ # :se => { # Northern Sami
723
+ # :one => "",
724
+ # :two => "",
725
+ # :other => ""
726
+ # },
727
+ #
728
+ # :sh => { # Not found
729
+ # :one => "",
730
+ # :few => "",
731
+ # :many => "",
732
+ # :other => ""
733
+ # },
734
+
735
+ :sk => { # Slovak
736
+ :one => "jablko",
737
+ :few => "jablká",
738
+ :other => "jabĺk"
739
+ },
740
+
741
+ :sl => { # Slovenian
742
+ :one => "jabolko",
743
+ :two => "jabolki",
744
+ :many => "jabolk",
745
+ :other => "apples"
746
+ },
747
+
748
+ # :sma => { # Southern Sami
749
+ # :one => "",
750
+ # :two => "",
751
+ # :other => ""
752
+ # },
753
+ #
754
+ # :smi => { # Sami languages
755
+ # :one => "",
756
+ # :two => "",
757
+ # :other => ""
758
+ # },
759
+ #
760
+ # :smj => { # Lule Sami
761
+ # :one => "",
762
+ # :two => "",
763
+ # :other => ""
764
+ # },
765
+ #
766
+ # :smn => { # Inari Sami
767
+ # :one => "",
768
+ # :two => "",
769
+ # :other => ""
770
+ # },
771
+ #
772
+ # :sms => { # Skolt Sami
773
+ # :one => "",
774
+ # :two => "",
775
+ # :other => ""
776
+ # },
777
+ #
778
+ # :so => { # Somali
779
+ # :one => "",
780
+ # :other => ""
781
+ # },
782
+
783
+ :sq => { # Albanian
784
+ :one => "molle",
785
+ :other => "mollë"
786
+ },
787
+
788
+
789
+ :sr => { # Serbian
790
+ :one => "јабука",
791
+ :few => "јабуке",
792
+ :many => "јабуке",
793
+ :other => "apples"
794
+ },
795
+
796
+ :sv => { # Swedish
797
+ :one => "äpple",
798
+ :other => "äpplen"
799
+ },
800
+
801
+ :sw => { # Swahili ; tree
802
+ :one => "mti",
803
+ :other => "miti"
804
+ },
805
+
806
+ :ta => { # Tamil
807
+ :one => "ஆப்பிள்",
808
+ :other => "ஆப்பிள்கள்"
809
+ },
810
+
811
+ :te => { # Telugu
812
+ :one => "ఆపిల్",
813
+ :other => "ఆపిల్ల"
814
+ },
815
+
816
+ :th => { # Thai
817
+ :other => "แอปเปิ้ล"
818
+ },
819
+
820
+ # :ti => { # Tigrinya
821
+ # :one => "",
822
+ # :other => ""
823
+ # },
824
+
825
+ # :tk => { # Turkmen
826
+ # :one => "",
827
+ # :other => ""
828
+ # },
829
+
830
+ # :tl => { # Tagalog
831
+ # :one => "",
832
+ # :other => ""
833
+ # },
834
+
835
+ # :to => { # Tonga (Tonga Islands)
836
+ # :other => ""
837
+ # },
838
+
839
+ :tr => { # Turkish
840
+ :other => "elma"
841
+ },
842
+
843
+ :uk => {
844
+ :one => "яблуко",
845
+ :few => "яблука",
846
+ :many => "яблук",
847
+ :other => "яблук"
848
+ },
849
+
850
+ :ur => { # Urdu
851
+ :one => "سیب",
852
+ :other => "سیب"
853
+ },
854
+
855
+ :vi => { # Vietnamese
856
+ :other => "quả táo"
857
+ },
858
+
859
+ # :wa => { # Walloon
860
+ # :one => "",
861
+ # :other => ""
862
+ # },
863
+ #
864
+ # :yo => { # Yoruba
865
+ # :other => ""
866
+ # },
867
+
868
+ :zh => { # Chinese
869
+ :other => "个苹果"
870
+ },
871
+
872
+ # :zu => { # Zulu
873
+ # :one => "",
874
+ # :other => ""
875
+ # }
876
+ })
877
+ end
878
+ end