@prosopo/locale 3.7.0 → 3.9.0

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.
Files changed (39) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +2 -2
  2. package/.turbo/turbo-build$colon$tsc.log +5 -5
  3. package/.turbo/turbo-build.log +3 -3
  4. package/CHANGELOG.md +38 -0
  5. package/dist/cjs/locales/en/translation.cjs +25 -2
  6. package/dist/locales/ar/translation.json +25 -2
  7. package/dist/locales/az/translation.json +25 -2
  8. package/dist/locales/cs/translation.json +25 -2
  9. package/dist/locales/de/translation.json +25 -2
  10. package/dist/locales/el/translation.json +25 -2
  11. package/dist/locales/en/translation.js +25 -2
  12. package/dist/locales/en/translation.json +25 -2
  13. package/dist/locales/es/translation.json +25 -2
  14. package/dist/locales/fi/translation.json +25 -2
  15. package/dist/locales/fr/translation.json +25 -2
  16. package/dist/locales/hi/translation.json +25 -2
  17. package/dist/locales/hu/translation.json +25 -2
  18. package/dist/locales/id/translation.json +25 -2
  19. package/dist/locales/it/translation.json +25 -2
  20. package/dist/locales/ja/translation.json +25 -2
  21. package/dist/locales/jv/translation.json +25 -2
  22. package/dist/locales/ko/translation.json +25 -2
  23. package/dist/locales/ml/translation.json +25 -2
  24. package/dist/locales/ms/translation.json +25 -2
  25. package/dist/locales/nl/translation.json +25 -2
  26. package/dist/locales/no/translation.json +25 -2
  27. package/dist/locales/pl/translation.json +25 -2
  28. package/dist/locales/pt/translation.json +25 -2
  29. package/dist/locales/pt-BR/translation.json +25 -2
  30. package/dist/locales/ro/translation.json +25 -2
  31. package/dist/locales/ru/translation.json +25 -2
  32. package/dist/locales/sr/translation.json +25 -2
  33. package/dist/locales/sv/translation.json +25 -2
  34. package/dist/locales/th/translation.json +25 -2
  35. package/dist/locales/tr/translation.json +25 -2
  36. package/dist/locales/uk/translation.json +25 -2
  37. package/dist/locales/vi/translation.json +25 -2
  38. package/dist/locales/zh-CN/translation.json +25 -2
  39. package/package.json +1 -1
@@ -25,9 +25,9 @@ dist/cjs/index.cjs 1.20 kB │ gzip: 0.34 kB
25
25
  dist/cjs/i18nBackend.cjs 1.47 kB │ gzip: 0.62 kB
26
26
  dist/cjs/loadI18next.cjs 2.03 kB │ gzip: 0.84 kB
27
27
  dist/cjs/i18nFrontend.cjs 6.07 kB │ gzip: 2.44 kB
28
- dist/cjs/locales/en/translation.cjs 17.51 kB │ gzip: 6.27 kB
28
+ dist/cjs/locales/en/translation.cjs 18.46 kB │ gzip: 6.61 kB
29
29
 
30
- ✓ built in 88ms
30
+ ✓ built in 75ms
31
31
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/ar/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/ar/translation.json
32
32
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/az/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/az/translation.json
33
33
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/cs/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/cs/translation.json
@@ -1,14 +1,14 @@
1
1
  $ tsc --build --verbose
2
- 1:37:21 PM - Projects in this build:
2
+ 11:33:01 AM - Projects in this build:
3
3
  * ../../dev/config/tsconfig.json
4
4
  * ../util/tsconfig.json
5
5
  * tsconfig.json
6
6
 
7
- 1:37:21 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
7
+ 11:33:01 AM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
8
8
 
9
- 1:37:21 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
9
+ 11:33:01 AM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
10
10
 
11
- 1:37:21 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
11
+ 11:33:01 AM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
12
12
 
13
- 1:37:21 PM - Building project '/home/runner/work/captcha/captcha/packages/locale/tsconfig.json'...
13
+ 11:33:01 AM - Building project '/home/runner/work/captcha/captcha/packages/locale/tsconfig.json'...
14
14
 
@@ -26,9 +26,9 @@ dist/translationKey.js 0.83 kB │ gzip: 0.43 kB
26
26
  dist/i18nBackend.js 1.01 kB │ gzip: 0.53 kB
27
27
  dist/loadI18next.js 1.93 kB │ gzip: 0.83 kB
28
28
  dist/i18nFrontend.js 5.98 kB │ gzip: 2.42 kB
29
- dist/locales/en/translation.js 17.27 kB │ gzip: 6.24 kB
29
+ dist/locales/en/translation.js 18.22 kB │ gzip: 6.57 kB
30
30
 
31
- ✓ built in 32ms
31
+ ✓ built in 249ms
32
32
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/ar/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/ar/translation.json
33
33
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/az/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/az/translation.json
34
34
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/cs/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/cs/translation.json
@@ -49,8 +49,8 @@ dist/locales/en/translation.js 17.27 kB │ gzip: 6.24 kB
49
49
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/ms/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/ms/translation.json
50
50
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/nl/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/nl/translation.json
51
51
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/no/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/no/translation.json
52
- [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/pt/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/pt/translation.json
53
52
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/pl/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/pl/translation.json
53
+ [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/pt/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/pt/translation.json
54
54
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/pt-BR/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/pt-BR/translation.json
55
55
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/ro/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/ro/translation.json
56
56
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/ru/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/ru/translation.json
package/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # @prosopo/locale
2
2
 
3
+ ## 3.9.0
4
+ ### Minor Changes
5
+
6
+ - 4570692: Let a user swap the puzzle captcha for an image challenge, on sites where Prosopo has switched it on.
7
+
8
+ Sites get a new staff-only setting, `widgetFeatureFlags.puzzleImageSwitch`. It is off by default and has no stored default. When it is on and the site allows image challenges, the puzzle response says `imageSwitchAvailable: true`. The puzzle then shows a small grid icon next to its title, with a "Switch to an image challenge" tooltip on hover or keyboard focus. After two wrong answers or refreshes in a row, the icon fills with the primary colour and its tooltip shows without a hover, because a touch screen has no hover. The tooltip goes away once the user starts moving the piece.
9
+
10
+ Pressing it re-mints the session the same way refresh does, with `switchToImage: true`. The provider only honours that when the request is a refresh of a puzzle session on the same site and the switch is on. The new session is then an image challenge with reason `PUZZLE_USER_SWITCH`. Like the refresh limit, it only ever moves from puzzle to image, so a client that fakes the request can only make its own challenge harder.
11
+
12
+ Also fixes a wrong puzzle answer restarting the whole widget. The user was sent back to the checkbox instead of getting a new puzzle with "Not quite — try again", and a wasted `/frictionless` request went out. The puzzle now retries in place.
13
+
14
+ ## 3.8.0
15
+ ### Minor Changes
16
+
17
+ - b299a91: An audio challenge, offered only as an accessibility alternative, like reCAPTCHA's audio option. The user hears a short sequence of spoken digits and types them in.
18
+
19
+ It is off by default and needs two switches. Prosopo has to turn on the `captchaTypeFeatureFlags.audio` feature flag for the site, which the site owner cannot do, and the site owner has to set `audioAccessibilityEnabled`. When both are on, image, puzzle and icon-order challenges show a "Use audio instead" button. Pressing it swaps the visual challenge for the audio one. After a wrong answer the user stays on audio and gets a fresh clip.
20
+
21
+ Audio is never a captcha type that can be selected or routed to. A site's `captchaType`, traffic-filter categories, Restrict rules and the site-key CLI all reject it, and routing, PoW escalation and the severity tiers leave it out. The provider only serves audio against the visual session the user was already given, and only on a site with both switches on; any other audio request is refused before the session is used up, and a request without a session is always refused.
22
+
23
+ The spoken digits are synthesised by `@prosopo/audio-assets`, so there is no recorded set of clips to collect. The answer never leaves the provider, and a challenge can be submitted and verified only once, even under concurrent requests. `@prosopo/procaptcha-audio` is the widget. It and the "Use audio instead" button are built on the shared widget code in `@prosopo/procaptcha-common`, and the provider side is built on the shared interactive-captcha code that puzzle and icon-order use.
24
+
25
+ The demo playground has audio pages, and there is an end-to-end test for it.
26
+
27
+ ### Patch Changes
28
+
29
+ - e13d7a8: New captcha type: `iconOrder`. The user is shown a frame of icons and a legend, and clicks the legend's icons in the order given.
30
+
31
+ Icon-order is off by default. Only Prosopo can switch it on for a site, with the `captchaTypeFeatureFlags.iconOrder` feature flag; the site owner cannot. A site without the flag is never served icon-order by any route, and the challenge endpoint refuses it. Once the flag is on, the owner can still keep icon-order out of the frictionless flow with `frictionlessTypes.iconOrder`, the same way as image and puzzle.
32
+
33
+ The answer never leaves the provider. Icon positions are stored on the challenge record, and the widget receives only the rendered frame and legend. Grading checks order as well as position, and each icon's hit radius scales with its size. Verifying a token is single-use under concurrent requests.
34
+
35
+ `@prosopo/icon-order-assets` draws the imagery, and `@prosopo/procaptcha-icon-order` is the widget. Its text is translated into every supported language.
36
+
37
+ Puzzle and icon-order now share their server code: challenge and solution handlers, the verify route, the submit and verify pipeline, and the database record methods. The widget code they have in common moves into `@prosopo/procaptcha-common`: the lazy mount wrapper, manager expiry and dispose, spent-session handling, behavioural data encryption and trusted click coordinates. Puzzle's behaviour is unchanged.
38
+
39
+ The demo playground has icon-order pages, and there is an end-to-end test for it.
40
+
3
41
  ## 3.7.0
4
42
  ### Minor Changes
5
43
 
@@ -28,8 +28,31 @@ var WIDGET = {
28
28
  "POSITION": "{{x}} percent across, {{y}} percent down",
29
29
  "CHECKING": "Checking your answer",
30
30
  "RETRY_ANNOUNCEMENT": "Not quite. A new puzzle has loaded and the piece is back at the start.",
31
- "REFRESH": "Show a different puzzle"
32
- }
31
+ "REFRESH": "Show a different puzzle",
32
+ "SWITCH_TO_IMAGE": "Switch to an image challenge",
33
+ "SWITCH_TO_IMAGE_ANNOUNCEMENT": "You can also switch to an image challenge."
34
+ },
35
+ "ICON_ORDER": {
36
+ "DIALOG_LABEL": "Icon order challenge",
37
+ "SELECT": "Select in this order",
38
+ "RETRY": "Not quite — try again",
39
+ "LEGEND_ALT": "Icons to select, in order",
40
+ "RESET": "Reset",
41
+ "CHECKING": "Checking…",
42
+ "SUBMIT": "OK"
43
+ },
44
+ "AUDIO_CHALLENGE_LABEL": "Audio verification challenge",
45
+ "AUDIO_INSTRUCTIONS": "Listen and type the {{count}} digits you hear.",
46
+ "AUDIO_INPUT_LABEL": "Type the {{count}} digits you hear",
47
+ "AUDIO_PLAY": "Play",
48
+ "AUDIO_REPLAY": "Play again",
49
+ "AUDIO_PLAYING": "Playing",
50
+ "AUDIO_FINISHED": "Playback finished",
51
+ "AUDIO_PLAYBACK_FAILED": "Audio could not be played. Check your device volume and try again.",
52
+ "AUDIO_INCORRECT": "That wasn't right. Here's a new one.",
53
+ "AUDIO_SUBMIT": "Verify",
54
+ "AUDIO_CHECKING": "Checking",
55
+ "AUDIO_ALTERNATIVE": "Use audio instead"
33
56
  };
34
57
  var GENERAL = {
35
58
  "JSON_LOAD_FAILED": "Failed to load JSON file",
@@ -399,8 +399,31 @@
399
399
  "POSITION": "{{x}} بالمئة من اليسار، {{y}} بالمئة من الأعلى",
400
400
  "CHECKING": "جارٍ التحقق من إجابتك",
401
401
  "RETRY_ANNOUNCEMENT": "اقتربت. تم تحميل أحجية جديدة وعادت القطعة إلى البداية.",
402
- "REFRESH": "أحجية مختلفة"
403
- }
402
+ "REFRESH": "أحجية مختلفة",
403
+ "SWITCH_TO_IMAGE": "التبديل إلى تحدي الصور",
404
+ "SWITCH_TO_IMAGE_ANNOUNCEMENT": "يمكنك أيضًا التبديل إلى تحدي الصور."
405
+ },
406
+ "ICON_ORDER": {
407
+ "DIALOG_LABEL": "تحدي ترتيب الأيقونات",
408
+ "SELECT": "اختر بهذا الترتيب",
409
+ "RETRY": "اقتربت — حاول مرة أخرى",
410
+ "LEGEND_ALT": "الأيقونات المطلوب اختيارها بالترتيب",
411
+ "RESET": "إعادة تعيين",
412
+ "CHECKING": "جارٍ التحقق…",
413
+ "SUBMIT": "موافق"
414
+ },
415
+ "AUDIO_CHALLENGE_LABEL": "Audio verification challenge",
416
+ "AUDIO_INSTRUCTIONS": "Listen and type the {{count}} digits you hear.",
417
+ "AUDIO_INPUT_LABEL": "Type the {{count}} digits you hear",
418
+ "AUDIO_PLAY": "Play",
419
+ "AUDIO_REPLAY": "Play again",
420
+ "AUDIO_PLAYING": "Playing",
421
+ "AUDIO_FINISHED": "Playback finished",
422
+ "AUDIO_PLAYBACK_FAILED": "Audio could not be played. Check your device volume and try again.",
423
+ "AUDIO_INCORRECT": "That wasn't right. Here's a new one.",
424
+ "AUDIO_SUBMIT": "Verify",
425
+ "AUDIO_CHECKING": "Checking",
426
+ "AUDIO_ALTERNATIVE": "Use audio instead"
404
427
  },
405
428
  "CONTRACT": {
406
429
  "INVALID_ADDRESS": "فشل في ترميز عنوان غير صالح",
@@ -399,8 +399,31 @@
399
399
  "POSITION": "soldan {{x}} faiz, yuxarıdan {{y}} faiz",
400
400
  "CHECKING": "Cavabınız yoxlanılır",
401
401
  "RETRY_ANNOUNCEMENT": "Az qaldı. Yeni tapmaca yükləndi və hissə yenidən başlanğıcdadır.",
402
- "REFRESH": "Başqa tapmaca"
403
- }
402
+ "REFRESH": "Başqa tapmaca",
403
+ "SWITCH_TO_IMAGE": "Şəkil tapşırığına keçin",
404
+ "SWITCH_TO_IMAGE_ANNOUNCEMENT": "Şəkil tapşırığına da keçə bilərsiniz."
405
+ },
406
+ "ICON_ORDER": {
407
+ "DIALOG_LABEL": "İkon sırası tapşırığı",
408
+ "SELECT": "Bu ardıcıllıqla seçin",
409
+ "RETRY": "Az qaldı — yenidən cəhd edin",
410
+ "LEGEND_ALT": "Seçiləcək ikonlar, ardıcıllıqla",
411
+ "RESET": "Sıfırla",
412
+ "CHECKING": "Yoxlanılır…",
413
+ "SUBMIT": "OK"
414
+ },
415
+ "AUDIO_CHALLENGE_LABEL": "Audio verification challenge",
416
+ "AUDIO_INSTRUCTIONS": "Listen and type the {{count}} digits you hear.",
417
+ "AUDIO_INPUT_LABEL": "Type the {{count}} digits you hear",
418
+ "AUDIO_PLAY": "Play",
419
+ "AUDIO_REPLAY": "Play again",
420
+ "AUDIO_PLAYING": "Playing",
421
+ "AUDIO_FINISHED": "Playback finished",
422
+ "AUDIO_PLAYBACK_FAILED": "Audio could not be played. Check your device volume and try again.",
423
+ "AUDIO_INCORRECT": "That wasn't right. Here's a new one.",
424
+ "AUDIO_SUBMIT": "Verify",
425
+ "AUDIO_CHECKING": "Checking",
426
+ "AUDIO_ALTERNATIVE": "Use audio instead"
404
427
  },
405
428
  "CONTRACT": {
406
429
  "INVALID_ADDRESS": "Geçərsiz ünvan kodlanmadı",
@@ -399,8 +399,31 @@
399
399
  "POSITION": "{{x}} procent zleva, {{y}} procent shora",
400
400
  "CHECKING": "Ověřujeme vaši odpověď",
401
401
  "RETRY_ANNOUNCEMENT": "Skoro. Načetla se nová skládačka a dílek je zpět na začátku.",
402
- "REFRESH": "Jiná skládačka"
403
- }
402
+ "REFRESH": "Jiná skládačka",
403
+ "SWITCH_TO_IMAGE": "Přepnout na obrázkový test",
404
+ "SWITCH_TO_IMAGE_ANNOUNCEMENT": "Můžete také přepnout na obrázkový test."
405
+ },
406
+ "ICON_ORDER": {
407
+ "DIALOG_LABEL": "Úloha s pořadím ikon",
408
+ "SELECT": "Vyberte v tomto pořadí",
409
+ "RETRY": "Skoro — zkuste to znovu",
410
+ "LEGEND_ALT": "Ikony k výběru, v daném pořadí",
411
+ "RESET": "Obnovit",
412
+ "CHECKING": "Ověřujeme…",
413
+ "SUBMIT": "OK"
414
+ },
415
+ "AUDIO_CHALLENGE_LABEL": "Audio verification challenge",
416
+ "AUDIO_INSTRUCTIONS": "Listen and type the {{count}} digits you hear.",
417
+ "AUDIO_INPUT_LABEL": "Type the {{count}} digits you hear",
418
+ "AUDIO_PLAY": "Play",
419
+ "AUDIO_REPLAY": "Play again",
420
+ "AUDIO_PLAYING": "Playing",
421
+ "AUDIO_FINISHED": "Playback finished",
422
+ "AUDIO_PLAYBACK_FAILED": "Audio could not be played. Check your device volume and try again.",
423
+ "AUDIO_INCORRECT": "That wasn't right. Here's a new one.",
424
+ "AUDIO_SUBMIT": "Verify",
425
+ "AUDIO_CHECKING": "Checking",
426
+ "AUDIO_ALTERNATIVE": "Use audio instead"
404
427
  },
405
428
  "CONTRACT": {
406
429
  "INVALID_ADDRESS": "Nepodařilo se zakódovat neplatnou adresu",
@@ -100,8 +100,31 @@
100
100
  "POSITION": "{{x}} Prozent von links, {{y}} Prozent von oben",
101
101
  "CHECKING": "Deine Antwort wird geprüft",
102
102
  "RETRY_ANNOUNCEMENT": "Knapp daneben. Ein neues Puzzle wurde geladen und das Teil steht wieder am Anfang.",
103
- "REFRESH": "Anderes Puzzle"
104
- }
103
+ "REFRESH": "Anderes Puzzle",
104
+ "SWITCH_TO_IMAGE": "Zu einer Bildaufgabe wechseln",
105
+ "SWITCH_TO_IMAGE_ANNOUNCEMENT": "Du kannst auch zu einer Bildaufgabe wechseln."
106
+ },
107
+ "ICON_ORDER": {
108
+ "DIALOG_LABEL": "Symbolreihenfolge-Aufgabe",
109
+ "SELECT": "In dieser Reihenfolge auswählen",
110
+ "RETRY": "Knapp daneben — versuche es erneut",
111
+ "LEGEND_ALT": "Auszuwählende Symbole, in Reihenfolge",
112
+ "RESET": "Zurücksetzen",
113
+ "CHECKING": "Wird geprüft…",
114
+ "SUBMIT": "OK"
115
+ },
116
+ "AUDIO_CHALLENGE_LABEL": "Audio verification challenge",
117
+ "AUDIO_INSTRUCTIONS": "Listen and type the {{count}} digits you hear.",
118
+ "AUDIO_INPUT_LABEL": "Type the {{count}} digits you hear",
119
+ "AUDIO_PLAY": "Play",
120
+ "AUDIO_REPLAY": "Play again",
121
+ "AUDIO_PLAYING": "Playing",
122
+ "AUDIO_FINISHED": "Playback finished",
123
+ "AUDIO_PLAYBACK_FAILED": "Audio could not be played. Check your device volume and try again.",
124
+ "AUDIO_INCORRECT": "That wasn't right. Here's a new one.",
125
+ "AUDIO_SUBMIT": "Verify",
126
+ "AUDIO_CHECKING": "Checking",
127
+ "AUDIO_ALTERNATIVE": "Use audio instead"
105
128
  },
106
129
  "CONTRACT": {
107
130
  "INVALID_ADDRESS": "Ungültige Adresse konnte nicht codiert werden",
@@ -399,8 +399,31 @@
399
399
  "POSITION": "{{x}} τοις εκατό από αριστερά, {{y}} τοις εκατό από πάνω",
400
400
  "CHECKING": "Ελέγχουμε την απάντησή σας",
401
401
  "RETRY_ANNOUNCEMENT": "Παραλίγο. Φορτώθηκε νέο παζλ και το κομμάτι επέστρεψε στην αρχή.",
402
- "REFRESH": "Άλλο παζλ"
403
- }
402
+ "REFRESH": "Άλλο παζλ",
403
+ "SWITCH_TO_IMAGE": "Μετάβαση σε δοκιμασία εικόνων",
404
+ "SWITCH_TO_IMAGE_ANNOUNCEMENT": "Μπορείτε επίσης να μεταβείτε σε δοκιμασία εικόνων."
405
+ },
406
+ "ICON_ORDER": {
407
+ "DIALOG_LABEL": "Δοκιμασία σειράς εικονιδίων",
408
+ "SELECT": "Επιλέξτε με αυτή τη σειρά",
409
+ "RETRY": "Παραλίγο — δοκιμάστε ξανά",
410
+ "LEGEND_ALT": "Εικονίδια για επιλογή, με τη σειρά",
411
+ "RESET": "Επαναφορά",
412
+ "CHECKING": "Γίνεται έλεγχος…",
413
+ "SUBMIT": "OK"
414
+ },
415
+ "AUDIO_CHALLENGE_LABEL": "Audio verification challenge",
416
+ "AUDIO_INSTRUCTIONS": "Listen and type the {{count}} digits you hear.",
417
+ "AUDIO_INPUT_LABEL": "Type the {{count}} digits you hear",
418
+ "AUDIO_PLAY": "Play",
419
+ "AUDIO_REPLAY": "Play again",
420
+ "AUDIO_PLAYING": "Playing",
421
+ "AUDIO_FINISHED": "Playback finished",
422
+ "AUDIO_PLAYBACK_FAILED": "Audio could not be played. Check your device volume and try again.",
423
+ "AUDIO_INCORRECT": "That wasn't right. Here's a new one.",
424
+ "AUDIO_SUBMIT": "Verify",
425
+ "AUDIO_CHECKING": "Checking",
426
+ "AUDIO_ALTERNATIVE": "Use audio instead"
404
427
  },
405
428
  "CONTRACT": {
406
429
  "INVALID_ADDRESS": "Αποτυχία κωδικοποίησης μη έγκυρης διεύθυνσης",
@@ -28,8 +28,31 @@ var WIDGET = {
28
28
  "POSITION": "{{x}} percent across, {{y}} percent down",
29
29
  "CHECKING": "Checking your answer",
30
30
  "RETRY_ANNOUNCEMENT": "Not quite. A new puzzle has loaded and the piece is back at the start.",
31
- "REFRESH": "Show a different puzzle"
32
- }
31
+ "REFRESH": "Show a different puzzle",
32
+ "SWITCH_TO_IMAGE": "Switch to an image challenge",
33
+ "SWITCH_TO_IMAGE_ANNOUNCEMENT": "You can also switch to an image challenge."
34
+ },
35
+ "ICON_ORDER": {
36
+ "DIALOG_LABEL": "Icon order challenge",
37
+ "SELECT": "Select in this order",
38
+ "RETRY": "Not quite — try again",
39
+ "LEGEND_ALT": "Icons to select, in order",
40
+ "RESET": "Reset",
41
+ "CHECKING": "Checking…",
42
+ "SUBMIT": "OK"
43
+ },
44
+ "AUDIO_CHALLENGE_LABEL": "Audio verification challenge",
45
+ "AUDIO_INSTRUCTIONS": "Listen and type the {{count}} digits you hear.",
46
+ "AUDIO_INPUT_LABEL": "Type the {{count}} digits you hear",
47
+ "AUDIO_PLAY": "Play",
48
+ "AUDIO_REPLAY": "Play again",
49
+ "AUDIO_PLAYING": "Playing",
50
+ "AUDIO_FINISHED": "Playback finished",
51
+ "AUDIO_PLAYBACK_FAILED": "Audio could not be played. Check your device volume and try again.",
52
+ "AUDIO_INCORRECT": "That wasn't right. Here's a new one.",
53
+ "AUDIO_SUBMIT": "Verify",
54
+ "AUDIO_CHECKING": "Checking",
55
+ "AUDIO_ALTERNATIVE": "Use audio instead"
33
56
  };
34
57
  var GENERAL = {
35
58
  "JSON_LOAD_FAILED": "Failed to load JSON file",
@@ -30,8 +30,31 @@
30
30
  "POSITION": "{{x}} percent across, {{y}} percent down",
31
31
  "CHECKING": "Checking your answer",
32
32
  "RETRY_ANNOUNCEMENT": "Not quite. A new puzzle has loaded and the piece is back at the start.",
33
- "REFRESH": "Show a different puzzle"
34
- }
33
+ "REFRESH": "Show a different puzzle",
34
+ "SWITCH_TO_IMAGE": "Switch to an image challenge",
35
+ "SWITCH_TO_IMAGE_ANNOUNCEMENT": "You can also switch to an image challenge."
36
+ },
37
+ "ICON_ORDER": {
38
+ "DIALOG_LABEL": "Icon order challenge",
39
+ "SELECT": "Select in this order",
40
+ "RETRY": "Not quite — try again",
41
+ "LEGEND_ALT": "Icons to select, in order",
42
+ "RESET": "Reset",
43
+ "CHECKING": "Checking…",
44
+ "SUBMIT": "OK"
45
+ },
46
+ "AUDIO_CHALLENGE_LABEL": "Audio verification challenge",
47
+ "AUDIO_INSTRUCTIONS": "Listen and type the {{count}} digits you hear.",
48
+ "AUDIO_INPUT_LABEL": "Type the {{count}} digits you hear",
49
+ "AUDIO_PLAY": "Play",
50
+ "AUDIO_REPLAY": "Play again",
51
+ "AUDIO_PLAYING": "Playing",
52
+ "AUDIO_FINISHED": "Playback finished",
53
+ "AUDIO_PLAYBACK_FAILED": "Audio could not be played. Check your device volume and try again.",
54
+ "AUDIO_INCORRECT": "That wasn't right. Here's a new one.",
55
+ "AUDIO_SUBMIT": "Verify",
56
+ "AUDIO_CHECKING": "Checking",
57
+ "AUDIO_ALTERNATIVE": "Use audio instead"
35
58
  },
36
59
  "GENERAL": {
37
60
  "JSON_LOAD_FAILED": "Failed to load JSON file",
@@ -100,8 +100,31 @@
100
100
  "POSITION": "{{x}} por ciento desde la izquierda, {{y}} por ciento desde arriba",
101
101
  "CHECKING": "Comprobando tu respuesta",
102
102
  "RETRY_ANNOUNCEMENT": "Casi. Se ha cargado un rompecabezas nuevo y la pieza vuelve a estar al principio.",
103
- "REFRESH": "Otro rompecabezas"
104
- }
103
+ "REFRESH": "Otro rompecabezas",
104
+ "SWITCH_TO_IMAGE": "Cambiar a un desafío de imágenes",
105
+ "SWITCH_TO_IMAGE_ANNOUNCEMENT": "También puedes cambiar a un desafío de imágenes."
106
+ },
107
+ "ICON_ORDER": {
108
+ "DIALOG_LABEL": "Desafío de orden de iconos",
109
+ "SELECT": "Selecciona en este orden",
110
+ "RETRY": "Casi — inténtalo de nuevo",
111
+ "LEGEND_ALT": "Iconos que seleccionar, en orden",
112
+ "RESET": "Restablecer",
113
+ "CHECKING": "Comprobando…",
114
+ "SUBMIT": "Aceptar"
115
+ },
116
+ "AUDIO_CHALLENGE_LABEL": "Audio verification challenge",
117
+ "AUDIO_INSTRUCTIONS": "Listen and type the {{count}} digits you hear.",
118
+ "AUDIO_INPUT_LABEL": "Type the {{count}} digits you hear",
119
+ "AUDIO_PLAY": "Play",
120
+ "AUDIO_REPLAY": "Play again",
121
+ "AUDIO_PLAYING": "Playing",
122
+ "AUDIO_FINISHED": "Playback finished",
123
+ "AUDIO_PLAYBACK_FAILED": "Audio could not be played. Check your device volume and try again.",
124
+ "AUDIO_INCORRECT": "That wasn't right. Here's a new one.",
125
+ "AUDIO_SUBMIT": "Verify",
126
+ "AUDIO_CHECKING": "Checking",
127
+ "AUDIO_ALTERNATIVE": "Use audio instead"
105
128
  },
106
129
  "CONTRACT": {
107
130
  "INVALID_ADDRESS": "Error al codificar dirección inválida",
@@ -437,8 +437,31 @@
437
437
  "POSITION": "{{x}} prosenttia vasemmalta, {{y}} prosenttia ylhäältä",
438
438
  "CHECKING": "Tarkistetaan vastaustasi",
439
439
  "RETRY_ANNOUNCEMENT": "Melkein. Uusi palapeli ladattiin ja pala on taas alussa.",
440
- "REFRESH": "Toinen palapeli"
441
- }
440
+ "REFRESH": "Toinen palapeli",
441
+ "SWITCH_TO_IMAGE": "Vaihda kuvatehtävään",
442
+ "SWITCH_TO_IMAGE_ANNOUNCEMENT": "Voit myös vaihtaa kuvatehtävään."
443
+ },
444
+ "ICON_ORDER": {
445
+ "DIALOG_LABEL": "Kuvakkeiden järjestystehtävä",
446
+ "SELECT": "Valitse tässä järjestyksessä",
447
+ "RETRY": "Melkein — yritä uudelleen",
448
+ "LEGEND_ALT": "Valittavat kuvakkeet järjestyksessä",
449
+ "RESET": "Tyhjennä",
450
+ "CHECKING": "Tarkistetaan…",
451
+ "SUBMIT": "OK"
452
+ },
453
+ "AUDIO_CHALLENGE_LABEL": "Audio verification challenge",
454
+ "AUDIO_INSTRUCTIONS": "Listen and type the {{count}} digits you hear.",
455
+ "AUDIO_INPUT_LABEL": "Type the {{count}} digits you hear",
456
+ "AUDIO_PLAY": "Play",
457
+ "AUDIO_REPLAY": "Play again",
458
+ "AUDIO_PLAYING": "Playing",
459
+ "AUDIO_FINISHED": "Playback finished",
460
+ "AUDIO_PLAYBACK_FAILED": "Audio could not be played. Check your device volume and try again.",
461
+ "AUDIO_INCORRECT": "That wasn't right. Here's a new one.",
462
+ "AUDIO_SUBMIT": "Verify",
463
+ "AUDIO_CHECKING": "Checking",
464
+ "AUDIO_ALTERNATIVE": "Use audio instead"
442
465
  },
443
466
  "CONTRACT": {
444
467
  "INVALID_ADDRESS": "Epäonnistui koodata virheellinen osoite",
@@ -100,8 +100,31 @@
100
100
  "POSITION": "{{x}} pour cent depuis la gauche, {{y}} pour cent depuis le haut",
101
101
  "CHECKING": "Vérification de votre réponse",
102
102
  "RETRY_ANNOUNCEMENT": "Presque. Un nouveau puzzle a été chargé et la pièce est revenue au départ.",
103
- "REFRESH": "Autre puzzle"
104
- }
103
+ "REFRESH": "Autre puzzle",
104
+ "SWITCH_TO_IMAGE": "Passer à un défi d'images",
105
+ "SWITCH_TO_IMAGE_ANNOUNCEMENT": "Vous pouvez aussi passer à un défi d'images."
106
+ },
107
+ "ICON_ORDER": {
108
+ "DIALOG_LABEL": "Défi d’ordre des icônes",
109
+ "SELECT": "Sélectionnez dans cet ordre",
110
+ "RETRY": "Presque — réessayez",
111
+ "LEGEND_ALT": "Icônes à sélectionner, dans l’ordre",
112
+ "RESET": "Réinitialiser",
113
+ "CHECKING": "Vérification…",
114
+ "SUBMIT": "OK"
115
+ },
116
+ "AUDIO_CHALLENGE_LABEL": "Audio verification challenge",
117
+ "AUDIO_INSTRUCTIONS": "Listen and type the {{count}} digits you hear.",
118
+ "AUDIO_INPUT_LABEL": "Type the {{count}} digits you hear",
119
+ "AUDIO_PLAY": "Play",
120
+ "AUDIO_REPLAY": "Play again",
121
+ "AUDIO_PLAYING": "Playing",
122
+ "AUDIO_FINISHED": "Playback finished",
123
+ "AUDIO_PLAYBACK_FAILED": "Audio could not be played. Check your device volume and try again.",
124
+ "AUDIO_INCORRECT": "That wasn't right. Here's a new one.",
125
+ "AUDIO_SUBMIT": "Verify",
126
+ "AUDIO_CHECKING": "Checking",
127
+ "AUDIO_ALTERNATIVE": "Use audio instead"
105
128
  },
106
129
  "CONTRACT": {
107
130
  "INVALID_ADDRESS": "Échec de l'encodage de l'adresse invalide",
@@ -399,8 +399,31 @@
399
399
  "POSITION": "बाएँ से {{x}} प्रतिशत, ऊपर से {{y}} प्रतिशत",
400
400
  "CHECKING": "आपका उत्तर जाँचा जा रहा है",
401
401
  "RETRY_ANNOUNCEMENT": "लगभग सही। एक नई पहेली आ गई है और टुकड़ा फिर से शुरुआत में है।",
402
- "REFRESH": "दूसरी पहेली"
403
- }
402
+ "REFRESH": "दूसरी पहेली",
403
+ "SWITCH_TO_IMAGE": "चित्र चुनौती पर जाएँ",
404
+ "SWITCH_TO_IMAGE_ANNOUNCEMENT": "आप चित्र चुनौती पर भी जा सकते हैं।"
405
+ },
406
+ "ICON_ORDER": {
407
+ "DIALOG_LABEL": "आइकन क्रम चुनौती",
408
+ "SELECT": "इस क्रम में चुनें",
409
+ "RETRY": "लगभग सही — फिर से कोशिश करें",
410
+ "LEGEND_ALT": "चुनने वाले आइकन, क्रम में",
411
+ "RESET": "रीसेट करें",
412
+ "CHECKING": "जाँच हो रही है…",
413
+ "SUBMIT": "ठीक है"
414
+ },
415
+ "AUDIO_CHALLENGE_LABEL": "Audio verification challenge",
416
+ "AUDIO_INSTRUCTIONS": "Listen and type the {{count}} digits you hear.",
417
+ "AUDIO_INPUT_LABEL": "Type the {{count}} digits you hear",
418
+ "AUDIO_PLAY": "Play",
419
+ "AUDIO_REPLAY": "Play again",
420
+ "AUDIO_PLAYING": "Playing",
421
+ "AUDIO_FINISHED": "Playback finished",
422
+ "AUDIO_PLAYBACK_FAILED": "Audio could not be played. Check your device volume and try again.",
423
+ "AUDIO_INCORRECT": "That wasn't right. Here's a new one.",
424
+ "AUDIO_SUBMIT": "Verify",
425
+ "AUDIO_CHECKING": "Checking",
426
+ "AUDIO_ALTERNATIVE": "Use audio instead"
404
427
  },
405
428
  "CONTRACT": {
406
429
  "INVALID_ADDRESS": "अवैध पता को एन्कोड करने में विफल रहा",
@@ -399,8 +399,31 @@
399
399
  "POSITION": "{{x}} százalék balról, {{y}} százalék fentről",
400
400
  "CHECKING": "Ellenőrizzük a válaszodat",
401
401
  "RETRY_ANNOUNCEMENT": "Majdnem. Új kirakós töltődött be, a darab pedig visszakerült a kiindulóhelyre.",
402
- "REFRESH": "Másik kirakós"
403
- }
402
+ "REFRESH": "Másik kirakós",
403
+ "SWITCH_TO_IMAGE": "Váltás képes feladatra",
404
+ "SWITCH_TO_IMAGE_ANNOUNCEMENT": "Képes feladatra is válthatsz."
405
+ },
406
+ "ICON_ORDER": {
407
+ "DIALOG_LABEL": "Ikonsorrend-feladat",
408
+ "SELECT": "Válasszon ebben a sorrendben",
409
+ "RETRY": "Majdnem — próbáld újra",
410
+ "LEGEND_ALT": "Kiválasztandó ikonok, sorrendben",
411
+ "RESET": "Visszaállítás",
412
+ "CHECKING": "Ellenőrzés…",
413
+ "SUBMIT": "OK"
414
+ },
415
+ "AUDIO_CHALLENGE_LABEL": "Audio verification challenge",
416
+ "AUDIO_INSTRUCTIONS": "Listen and type the {{count}} digits you hear.",
417
+ "AUDIO_INPUT_LABEL": "Type the {{count}} digits you hear",
418
+ "AUDIO_PLAY": "Play",
419
+ "AUDIO_REPLAY": "Play again",
420
+ "AUDIO_PLAYING": "Playing",
421
+ "AUDIO_FINISHED": "Playback finished",
422
+ "AUDIO_PLAYBACK_FAILED": "Audio could not be played. Check your device volume and try again.",
423
+ "AUDIO_INCORRECT": "That wasn't right. Here's a new one.",
424
+ "AUDIO_SUBMIT": "Verify",
425
+ "AUDIO_CHECKING": "Checking",
426
+ "AUDIO_ALTERNATIVE": "Use audio instead"
404
427
  },
405
428
  "CONTRACT": {
406
429
  "INVALID_ADDRESS": "Nem sikerült kódolni az érvénytelen címet",
@@ -399,8 +399,31 @@
399
399
  "POSITION": "{{x}} persen dari kiri, {{y}} persen dari atas",
400
400
  "CHECKING": "Memeriksa jawaban Anda",
401
401
  "RETRY_ANNOUNCEMENT": "Nyaris. Teka-teki baru telah dimuat dan kepingan kembali ke awal.",
402
- "REFRESH": "Teka-teki lain"
403
- }
402
+ "REFRESH": "Teka-teki lain",
403
+ "SWITCH_TO_IMAGE": "Beralih ke tantangan gambar",
404
+ "SWITCH_TO_IMAGE_ANNOUNCEMENT": "Anda juga dapat beralih ke tantangan gambar."
405
+ },
406
+ "ICON_ORDER": {
407
+ "DIALOG_LABEL": "Tantangan urutan ikon",
408
+ "SELECT": "Pilih dalam urutan ini",
409
+ "RETRY": "Nyaris — coba lagi",
410
+ "LEGEND_ALT": "Ikon yang harus dipilih, berurutan",
411
+ "RESET": "Atur ulang",
412
+ "CHECKING": "Memeriksa…",
413
+ "SUBMIT": "OK"
414
+ },
415
+ "AUDIO_CHALLENGE_LABEL": "Audio verification challenge",
416
+ "AUDIO_INSTRUCTIONS": "Listen and type the {{count}} digits you hear.",
417
+ "AUDIO_INPUT_LABEL": "Type the {{count}} digits you hear",
418
+ "AUDIO_PLAY": "Play",
419
+ "AUDIO_REPLAY": "Play again",
420
+ "AUDIO_PLAYING": "Playing",
421
+ "AUDIO_FINISHED": "Playback finished",
422
+ "AUDIO_PLAYBACK_FAILED": "Audio could not be played. Check your device volume and try again.",
423
+ "AUDIO_INCORRECT": "That wasn't right. Here's a new one.",
424
+ "AUDIO_SUBMIT": "Verify",
425
+ "AUDIO_CHECKING": "Checking",
426
+ "AUDIO_ALTERNATIVE": "Use audio instead"
404
427
  },
405
428
  "CONTRACT": {
406
429
  "INVALID_ADDRESS": "Gagal mengkodekan alamat yang tidak valid",
@@ -100,8 +100,31 @@
100
100
  "POSITION": "{{x}} percento da sinistra, {{y}} percento dall'alto",
101
101
  "CHECKING": "Verifica della tua risposta in corso",
102
102
  "RETRY_ANNOUNCEMENT": "Quasi. È stato caricato un nuovo puzzle e il pezzo è tornato all'inizio.",
103
- "REFRESH": "Un altro puzzle"
104
- }
103
+ "REFRESH": "Un altro puzzle",
104
+ "SWITCH_TO_IMAGE": "Passa a una sfida con immagini",
105
+ "SWITCH_TO_IMAGE_ANNOUNCEMENT": "Puoi anche passare a una sfida con immagini."
106
+ },
107
+ "ICON_ORDER": {
108
+ "DIALOG_LABEL": "Sfida sull’ordine delle icone",
109
+ "SELECT": "Seleziona in questo ordine",
110
+ "RETRY": "Quasi — riprova",
111
+ "LEGEND_ALT": "Icone da selezionare, in ordine",
112
+ "RESET": "Reimposta",
113
+ "CHECKING": "Verifica in corso…",
114
+ "SUBMIT": "OK"
115
+ },
116
+ "AUDIO_CHALLENGE_LABEL": "Audio verification challenge",
117
+ "AUDIO_INSTRUCTIONS": "Listen and type the {{count}} digits you hear.",
118
+ "AUDIO_INPUT_LABEL": "Type the {{count}} digits you hear",
119
+ "AUDIO_PLAY": "Play",
120
+ "AUDIO_REPLAY": "Play again",
121
+ "AUDIO_PLAYING": "Playing",
122
+ "AUDIO_FINISHED": "Playback finished",
123
+ "AUDIO_PLAYBACK_FAILED": "Audio could not be played. Check your device volume and try again.",
124
+ "AUDIO_INCORRECT": "That wasn't right. Here's a new one.",
125
+ "AUDIO_SUBMIT": "Verify",
126
+ "AUDIO_CHECKING": "Checking",
127
+ "AUDIO_ALTERNATIVE": "Use audio instead"
105
128
  },
106
129
  "CONTRACT": {
107
130
  "INVALID_ADDRESS": "Impossibile codificare l'indirizzo non valido",