Compare commits

...

212 Commits

Author SHA1 Message Date
Danny Coates
9714bb0a0a v1.1.1 2017-08-16 18:29:35 -07:00
Danny Coates
ad82d30dd9 Merge pull request #516 from mozilla/cache-assets
cache assets
2017-08-16 17:44:09 -07:00
Danny Coates
757ac14d1a webpacked the heck out of the build 2017-08-16 14:21:01 -07:00
Danny Coates
3e066258c4 Merge pull request #520 from mozilla/i519
fix drag & drop
2017-08-16 11:11:46 -07:00
Danny Coates
127f73b4fe fixes #519 drag & drop 2017-08-16 11:03:17 -07:00
Emin Mastizada
ae5009e1e3 Pontoon: Update Azerbaijani (az) localization of Test Pilot: Firefox Send
Localization authors:
- Emin Mastizada <emin@mastizada.com>
2017-08-16 07:31:19 +00:00
Danny Coates
0ab8ddc894 groundwork for asset caching 2017-08-15 11:55:52 -07:00
Danny Coates
b429841534 use new upload button string 2017-08-15 10:30:19 -07:00
jesferman1993
279f6df6f4 Pontoon: Update Spanish (es-ES) localization of Test Pilot: Firefox Send
Localization authors:
- jesferman1993 <jesferman1993@hotmail.com>
2017-08-15 09:11:11 +00:00
Slimane Amiri
634e6b2834 Pontoon: Update Kabyle (kab) localization of Test Pilot: Firefox Send
Localization authors:
- Slimane Amiri <slimane.amiri@gmail.com>
2017-08-15 07:31:06 +00:00
Danny Coates
856b2cdc60 Merge pull request #515 from mozilla/refactor-upload
removed jquery from upload.js
2017-08-14 21:23:04 -07:00
Danny Coates
41351f877c removed jquery from upload.js 2017-08-14 20:00:14 -07:00
Andreas Pettersson
afbb89fbe8 Pontoon: Update Swedish (sv-SE) localization of Test Pilot: Firefox Send
Localization authors:
- Andreas Pettersson <az@kth.se>
2017-08-14 22:31:48 +00:00
Pierre Neter
b40b45273d Pontoon: Update Vietnamese (vi) localization of Test Pilot: Firefox Send
Localization authors:
- Pierre Neter <pierreneter@gmail.com>
2017-08-14 19:31:32 +00:00
Danny Coates
f1fb877c7f Merge pull request #514 from mozilla/refactor-download
use async and removed jquery from download.js
2017-08-14 12:12:11 -07:00
Jon Vadillo
9d7ad06b1a Pontoon: Update Spanish (es-ES) localization of Test Pilot: Firefox Send
Localization authors:
- Jon Vadillo <vadillo.jon@gmail.com>
2017-08-14 18:30:39 +00:00
Danny Coates
c6a4b089d9 use async and removed jquery from download.js 2017-08-14 11:14:47 -07:00
Danny Coates
24917f8aa5 Merge pull request #513 from mozilla/svg-progress
use svg for progress
2017-08-14 10:05:03 -07:00
Danny Coates
eada94b262 use svg for progress 2017-08-13 18:46:05 -07:00
Danny Coates
43fa551a64 improved exist check 2017-08-13 18:44:59 -07:00
Roberto Alvarado
e1137db946 Pontoon: Update Spanish (es-MX) localization of Test Pilot: Firefox Send
Localization authors:
- Roberto Alvarado <ralv888@gmail.com>
2017-08-14 00:50:56 +00:00
Enol
c1878649b3 Pontoon: Update Asturian (ast) localization of Test Pilot: Firefox Send
Localization authors:
- Enol <enolp@softastur.org>
2017-08-13 17:50:44 +00:00
Michael Wolf
30b86b14ed Pontoon: Update Sorbian, Upper (hsb) localization of Test Pilot: Firefox Send
Localization authors:
- Michael Wolf <milupo@sorbzilla.de>
2017-08-13 15:31:13 +00:00
Michael Wolf
e91b341f8a Pontoon: Update Sorbian, Lower (dsb) localization of Test Pilot: Firefox Send
Localization authors:
- Michael Wolf <milupo@sorbzilla.de>
2017-08-13 15:31:11 +00:00
Jakub Rychlý
70148232c6 Pontoon: Update Czech (cs) localization of Test Pilot: Firefox Send
Localization authors:
- Jakub Rychlý <jrychly@jakubrychly.cz>
- sajdl.vojtech <sajdl.vojtech@gmail.com>
2017-08-13 12:31:06 +00:00
Alexander Slovesnik
56e3d5766c Pontoon: Update Russian (ru) localization of Test Pilot: Firefox Send
Localization authors:
- Alexander Slovesnik <unghost@mozilla-russia.org>
2017-08-12 22:11:20 +00:00
Rhoslyn Prys
350e31ae4a Pontoon: Update Welsh (cy) localization of Test Pilot: Firefox Send
Localization authors:
- Rhoslyn Prys <rprys@yahoo.com>
2017-08-12 19:31:25 +00:00
Marcelo Poli
0794bcc458 Pontoon: Update Spanish (es-AR) localization of Test Pilot: Firefox Send
Localization authors:
- Marcelo Poli <enzomatrix@gmail.com>
2017-08-12 18:31:01 +00:00
Belayet Hossain
a6aee8ad62 Pontoon: Update Bengali (bn-BD) localization of Test Pilot: Firefox Send
Localization authors:
- Belayet Hossain <bellayet@gmail.com>
- S M Sarwar Nobin <smsarwar1996@gmail.com>
2017-08-12 18:30:59 +00:00
josotrix
8305d13dab Pontoon: Update Spanish (es-CL) localization of Test Pilot: Firefox Send
Localization authors:
- josotrix <josotrix@ravmn.cl>
2017-08-12 17:11:33 +00:00
Selim Şumlu
441a520765 Pontoon: Update Turkish (tr) localization of Test Pilot: Firefox Send
Localization authors:
- Selim Şumlu <selim@sum.lu>
2017-08-12 15:50:46 +00:00
josotrix
ba84e59f39 Pontoon: Update Spanish (es-CL) localization of Test Pilot: Firefox Send
Localization authors:
- josotrix <josotrix@ravmn.cl>
- ravmn <ravmn@ravmn.cl>
2017-08-12 15:50:43 +00:00
Pin-guang Chen
22a316ab58 Pontoon: Update Chinese (zh-TW) localization of Test Pilot: Firefox Send
Localization authors:
- Pin-guang Chen <petercpg@mail.moztw.org>
2017-08-12 15:31:26 +00:00
Juraj Cigáň
6b9502d252 Pontoon: Update Slovak (sk) localization of Test Pilot: Firefox Send
Localization authors:
- Juraj Cigáň <kusavica@gmail.com>
2017-08-12 12:11:21 +00:00
Danny Coates
cdc3a5340d defer main js scripts 2017-08-11 19:13:57 -07:00
Danny Coates
f03f7a0286 Merge pull request #510 from mozilla/hooks
added precommit hook for format
2017-08-11 18:34:48 -07:00
Danny Coates
d8a5789701 added precommit hook for format 2017-08-11 18:06:16 -07:00
Danny Coates
8d26e0e742 Merge pull request #502 from mozilla/refactor-filelist
extracted filelist into its own file
2017-08-11 14:18:35 -07:00
Danny Coates
e142d76cb4 Merge pull request #428 from mozilla/add-twitter-og-cards
add twitter and open graph cards
2017-08-11 14:12:44 -07:00
Danny Coates
c488c1d724 added BASE_URL environment variable 2017-08-11 14:02:44 -07:00
Danny Coates
bed57af6c5 extracted filelist into its own file 2017-08-11 13:50:58 -07:00
Jim Spentzos
7500bd8326 Pontoon: Update Greek (el) localization of Test Pilot: Firefox Send
Localization authors:
- Jim Spentzos <jamesspentzos@hotmail.com>
- Μιχάλης <mikem132@protonmail.com>
2017-08-11 20:31:46 +00:00
Danny Coates
0250924961 Merge pull request #506 from varghesethomase/404-page
404 page
2017-08-11 12:20:02 -07:00
Varghese Thomas
70813556ad Reverting unwanted notfound page response 2017-08-12 00:29:25 +05:30
Марко Костић (Marko Kostić)
2bb9af1943 Pontoon: Update Serbian (sr) localization of Test Pilot: Firefox Send
Localization authors:
- Марко Костић (Marko Kostić) <marko.m.kostic@gmail.com>
2017-08-11 18:51:01 +00:00
Danny Coates
55bd44a8f5 Merge pull request #508 from mozilla/fixes478
fixes 478
2017-08-11 10:58:24 -07:00
Abhinav Adduri
d83900f272 fixes 478 2017-08-11 10:50:37 -07:00
Jordi Serratosa
fa4f9299b2 Pontoon: Update Catalan (ca) localization of Test Pilot: Firefox Send
Localization authors:
- Jordi Serratosa <jordis@softcatala.cat>
2017-08-11 16:31:45 +00:00
Danny Coates
0f7b19c385 Merge pull request #504 from mozilla/fix-japanese-browse-btn
fix japanese browse button
2017-08-11 08:37:34 -07:00
Varghese Thomas
a9c1dd0180 Replacing all send status 404 with notfound page 2017-08-11 20:52:18 +05:30
Varghese Thomas
c468e2f34e Sending not found page for invalid url id 2017-08-11 20:46:59 +05:30
Michael Köhler
718f42897f Pontoon: Update German (de) localization of Test Pilot: Firefox Send
Localization authors:
- Michael Köhler <michael.koehler1@gmx.de>
2017-08-11 13:31:09 +00:00
John Gruen
fb468bd1bc fix japanese browse button 2017-08-11 13:41:14 +02:00
John Gruen
dafe00cabb add twitter and open graph cards 2017-08-11 13:39:04 +02:00
Matjaž Horvat
98aebb7f70 Pontoon: Update Slovenian (sl) localization of Test Pilot: Firefox Send
Localization authors:
- Matjaž Horvat <matjaz.horvat@gmail.com>
2017-08-11 11:31:10 +00:00
Tymur Faradzhev
a990d78bc0 Pontoon: Update Ukrainian (uk) localization of Test Pilot: Firefox Send
Localization authors:
- Tymur Faradzhev <faradzhev.timur@gmail.com>
2017-08-11 08:31:11 +00:00
Balázs Meskó
9b4069be3e Pontoon: Update Hungarian (hu) localization of Test Pilot: Firefox Send
Localization authors:
- Balázs Meskó <meskobalazs@gmail.com>
2017-08-11 08:31:08 +00:00
Håvar Henriksen
ff3bc0dd62 Pontoon: Update Norwegian Bokmål (nb-NO) localization of Test Pilot: Firefox Send
Localization authors:
- Håvar Henriksen <havar@firefox.no>
2017-08-11 06:50:58 +00:00
Luna Jernberg
b39b131928 Pontoon: Update Swedish (sv-SE) localization of Test Pilot: Firefox Send
Localization authors:
- Luna Jernberg <bittin@cafe8bitar.se>
2017-08-11 03:31:14 +00:00
Danny Coates
2646fb9b3c Merge pull request #503 from skystar-p/editorconfig
Added editorconfig
2017-08-10 19:50:46 -07:00
skystar-p
c2b84650e2 added editorconfig 2017-08-11 11:39:56 +09:00
YFdyh000
fecf938ae7 Pontoon: Update Chinese (zh-CN) localization of Test Pilot: Firefox Send
Localization authors:
- YFdyh000 <yfdyh000@gmail.com>
2017-08-11 02:31:45 +00:00
Cláudio Esperança
8abf631430 Pontoon: Update Portuguese (pt-PT) localization of Test Pilot: Firefox Send
Localization authors:
- Cláudio Esperança <cesperanc@gmail.com>
2017-08-11 02:10:43 +00:00
manxmensch
d69c535dda Pontoon: Update Malay (ms) localization of Test Pilot: Firefox Send
Localization authors:
- manxmensch <manxmensch@gmail.com>
2017-08-11 00:50:39 +00:00
Kohei Yoshino
082ca6c57b Pontoon: Update Japanese (ja) localization of Test Pilot: Firefox Send
Localization authors:
- Kohei Yoshino <kohei.yoshino@gmail.com>
2017-08-10 22:10:52 +00:00
Bjørn I
b263231068 Pontoon: Update Norwegian Nynorsk (nn-NO) localization of Test Pilot: Firefox Send
Localization authors:
- Bjørn I. <bjorn.svindseth@online.no>
2017-08-10 20:31:46 +00:00
Francesco Lodolo
947a6d9992 Pontoon: Update Italian (it) localization of Test Pilot: Firefox Send
Localization authors:
- Francesco Lodolo <francesco.lodolo@mozillaitalia.org>
2017-08-10 20:10:54 +00:00
Danny Coates
1ad7edf5a9 fixed bad merge 2017-08-10 12:59:07 -07:00
Schieck :)
0c26204ea1 Pontoon: Update Portuguese (pt-BR) localization of Test Pilot: Firefox Send
Localization authors:
- Schieck :) <ricardoschieck@gmail.com>
2017-08-10 18:51:14 +00:00
Ton
1e3bbee7f1 Pontoon: Update Dutch (nl) localization of Test Pilot: Firefox Send
Localization authors:
- Ton <tonnes.mb@gmail.com>
2017-08-10 18:11:25 +00:00
Danny Coates
ec80e8e622 Merge pull request #499 from mozilla/pier1
use import/export in the frontend code
2017-08-10 11:07:38 -07:00
Théo Chevalier
61e2c0d85b Pontoon: Update French (fr) localization of Test Pilot: Firefox Send
Localization authors:
- Théo Chevalier <theo.chevalier11@gmail.com>
2017-08-10 17:50:53 +00:00
Danny Coates
80db74fc3a Merge pull request #500 from mozilla/i495
fixed build:css on windows
2017-08-10 10:43:07 -07:00
Danny Coates
30936eb2fa fixed build:css on windows 2017-08-10 10:38:36 -07:00
Danny Coates
31e29d58b9 Merge pull request #481 from pdehaan/fix-l10n-id
Cater for mobile and desktop
2017-08-10 10:19:21 -07:00
Danny Coates
702134b3b1 use import/export in the frontend code 2017-08-10 10:03:22 -07:00
Danny Coates
11ae7f857c Merge pull request #493 from mozilla/webpack-dev
added webpack-dev-middleware
2017-08-10 09:29:43 -07:00
Peter deHaan
8827556974 Add new l10n string, but don't use it yet 2017-08-10 09:26:25 -07:00
Danny Coates
21b7f16b1e added webpack-dev-middleware for recompiling on source changes 2017-08-10 09:23:33 -07:00
Danny Coates
314ab237ec Merge pull request #491 from mozilla/i387
added missing exit event cases
2017-08-10 09:06:57 -07:00
Danny Coates
0fa0416c3f Merge pull request #492 from mozilla/no-cookies
make the site mostly work when cookies (localStorage) are disabled
2017-08-10 09:06:15 -07:00
Danny Coates
09faedf059 make the site mostly work when cookies (localStorage) are disabled 2017-08-09 23:12:15 -07:00
Danny Coates
16aa7983ed added missing exit event cases 2017-08-09 16:44:09 -07:00
Marcelo Poli
493bf8dc89 Pontoon: Update Spanish (es-AR) localization of Test Pilot: Firefox Send
Localization authors:
- Marcelo Poli <enzomatrix@gmail.com>
2017-08-09 22:10:59 +00:00
Danny Coates
46432b9649 Merge pull request #490 from mozilla/i489
set the mime type in the download blob
2017-08-09 14:31:55 -07:00
Danny Coates
193664a8e8 set the mime type in the download blob 2017-08-09 14:25:37 -07:00
Danny Coates
626e578acb Merge pull request #485 from mozilla/i479
added progress to tab title when not in focus
2017-08-09 11:42:35 -07:00
Tymur Faradzhev
51bffe11a8 Pontoon: Update Ukrainian (uk) localization of Test Pilot: Firefox Send
Localization authors:
- Tymur Faradzhev <faradzhev.timur@gmail.com>
2017-08-09 08:10:36 +00:00
Danny Coates
08e2c6c112 Merge pull request #474 from varghesethomase/master
Fixing bug #438 by adding role attribute to anchor tags and alt attribute images
2017-08-08 22:41:31 -07:00
Danny Coates
c38d91db98 added progress to tab title when not in focus 2017-08-08 20:23:38 -07:00
Danny Coates
c13839a522 Merge pull request #480 from pdehaan/issue-443
Increase font weight to 500 on <button>s and <label>s
2017-08-08 19:43:46 -07:00
Peter deHaan
4894d5162f Update l10n id 2017-08-08 13:37:33 -07:00
Peter deHaan
77b6fb138f Increase font weight to 500 on <button>s and <label>s 2017-08-08 13:06:59 -07:00
Danny Coates
9dab74891d Merge pull request #419 from pdehaan/autoprefixer
Add autoprefixer and cssnano support
2017-08-08 12:43:56 -07:00
Enol
393d2a0052 Pontoon: Update Asturian (ast) localization of Test Pilot: Firefox Send
Localization authors:
- Enol <enolp@softastur.org>
2017-08-08 19:31:58 +00:00
Enol
44ac783f6a Pontoon: Update Asturian (ast) localization of Test Pilot: Firefox Send
Localization authors:
- Enol <enolp@softastur.org>
2017-08-08 18:50:58 +00:00
Enol
7ea8712538 Pontoon: Update Asturian (ast) localization of Test Pilot: Firefox Send
Localization authors:
- Enol <enolp@softastur.org>
2017-08-08 18:30:54 +00:00
Jordi Serratosa
fb92a793e4 Pontoon: Update Catalan (ca) localization of Test Pilot: Firefox Send
Localization authors:
- Jordi Serratosa <jordis@softcatala.cat>
2017-08-08 12:50:40 +00:00
Luna Jernberg
87eaba6337 Pontoon: Update Swedish (sv-SE) localization of Test Pilot: Firefox Send
Localization authors:
- Luna Jernberg <bittin@cafe8bitar.se>
2017-08-08 11:31:17 +00:00
Selim Şumlu
7e13f2ab32 Pontoon: Update Turkish (tr) localization of Test Pilot: Firefox Send
Localization authors:
- Selim Şumlu <selim@sum.lu>
2017-08-08 11:11:10 +00:00
Slimane Amiri
3214d293ca Pontoon: Update Kabyle (kab) localization of Test Pilot: Firefox Send
Localization authors:
- Slimane Amiri <slimane.amiri@gmail.com>
2017-08-08 10:10:28 +00:00
Håvar Henriksen
1437116cf3 Pontoon: Update Norwegian Bokmål (nb-NO) localization of Test Pilot: Firefox Send
Localization authors:
- Håvar Henriksen <havar@firefox.no>
2017-08-08 07:31:23 +00:00
Danny Coates
87a8cfba40 v1.1.0 2017-08-07 20:59:39 -07:00
Jae Hyeon Park
f929bb2aec Pontoon: Update Korean (ko) localization of Test Pilot: Firefox Send
Localization authors:
- Hyeonseok Shin <hyeonseok@gmail.com>
- Jae Hyeon Park <wogus150@naver.com>
2017-08-08 02:50:53 +00:00
Varghese Thomas
740001ddde Fixing bug #438 by adding role attribute to anchor tags and alt attributes to images. Also solves #440 2017-08-08 08:05:02 +05:30
Pin-guang Chen
aaec16cf52 Pontoon: Update Chinese (zh-TW) localization of Test Pilot: Firefox Send
Localization authors:
- Pin-guang Chen <petercpg@mail.moztw.org>
2017-08-08 02:31:08 +00:00
Peter deHaan
24af3207e9 Update browserslist 2017-08-07 16:38:19 -07:00
Pierre Neter
5da43f0da7 Pontoon: Update Vietnamese (vi) localization of Test Pilot: Firefox Send
Localization authors:
- Pierre Neter <pierreneter@gmail.com>
2017-08-07 23:30:51 +00:00
Bjørn I
dffb26349b Pontoon: Update Norwegian Nynorsk (nn-NO) localization of Test Pilot: Firefox Send
Localization authors:
- Bjørn I. <bjorn.svindseth@online.no>
2017-08-07 23:30:49 +00:00
Peter deHaan
38746078ed Add autoprefixer and cssnano support 2017-08-07 16:19:40 -07:00
manxmensch
c4751842fe Pontoon: Update Malay (ms) localization of Test Pilot: Firefox Send
Localization authors:
- manxmensch <manxmensch@gmail.com>
2017-08-07 22:50:48 +00:00
Danny Coates
08ec9d98b8 Merge pull request #473 from pdehaan/fix-contributors
Sort contributors alphabetically to prevent churn
2017-08-07 15:41:06 -07:00
Danny Coates
5200928d5c Merge pull request #472 from mozilla/remove-hash-tests
removed references to checksums in frontend tests
2017-08-07 15:36:29 -07:00
Peter deHaan
4c3e37f4b5 Sort contributors alphabetically to prevent churn 2017-08-07 15:24:27 -07:00
Abhinav Adduri
60eda64c8d linting 2017-08-07 15:12:11 -07:00
Abhinav Adduri
4db7fc6db3 removed references to checksums in frontend tests 2017-08-07 14:58:22 -07:00
Danny Coates
5844a9a03c Merge pull request #470 from mozilla/remove-hash
removed the file sha256 hash
2017-08-07 14:42:53 -07:00
YFdyh000
9829e46270 Pontoon: Update Chinese (zh-CN) localization of Test Pilot: Firefox Send
Localization authors:
- YFdyh000 <yfdyh000@gmail.com>
2017-08-07 21:30:49 +00:00
Danny Coates
9a150ddb22 removed the file sha256 hash 2017-08-07 14:05:13 -07:00
Marcelo Poli
e7b90ea1b9 Pontoon: Update Spanish (es-AR) localization of Test Pilot: Firefox Send
Localization authors:
- Marcelo Poli <enzomatrix@gmail.com>
2017-08-07 19:51:18 +00:00
Balázs Meskó
07bcfa2d36 Pontoon: Update Hungarian (hu) localization of Test Pilot: Firefox Send
Localization authors:
- Balázs Meskó <meskobalazs@gmail.com>
2017-08-07 19:51:16 +00:00
Juraj Cigáň
dce134744d Pontoon: Update Slovak (sk) localization of Test Pilot: Firefox Send
Localization authors:
- Juraj Cigáň <kusavica@gmail.com>
2017-08-07 19:31:07 +00:00
Michael Wolf
288bc50484 Pontoon: Update Sorbian, Upper (hsb) localization of Test Pilot: Firefox Send
Localization authors:
- Michael Wolf <milupo@sorbzilla.de>
2017-08-07 19:11:05 +00:00
Michael Wolf
09d6c64a9b Pontoon: Update Sorbian, Lower (dsb) localization of Test Pilot: Firefox Send
Localization authors:
- Michael Wolf <milupo@sorbzilla.de>
2017-08-07 19:11:00 +00:00
Francesco Lodolo
d7a542f2c2 Pontoon: Update Italian (it) localization of Test Pilot: Firefox Send
Localization authors:
- Francesco Lodolo <francesco.lodolo@mozillaitalia.org>
2017-08-07 19:10:55 +00:00
Danny Coates
aca82dd880 Merge pull request #469 from ehuggett/patch-1
Increase mimimum node version to 8.2.0
2017-08-07 12:03:59 -07:00
Danny Coates
aa72a4c72c Merge pull request #468 from mozilla/i465
attach delete-file handler only after upload
2017-08-07 12:03:17 -07:00
Марко Костић (Marko Kostić)
a70dcfc905 Pontoon: Update Serbian (sr) localization of Test Pilot: Firefox Send
Localization authors:
- Марко Костић (Marko Kostić) <marko.m.kostic@gmail.com>
2017-08-07 18:50:39 +00:00
Kohei Yoshino
49731ab8ba Pontoon: Update Japanese (ja) localization of Test Pilot: Firefox Send
Localization authors:
- Kohei Yoshino <kohei.yoshino@gmail.com>
2017-08-07 18:50:34 +00:00
ehuggett
3d9e01f8e5 Increase mimimun node version to 8.2.0
This version has a useful protection against http header splitting
2017-08-07 19:50:10 +01:00
Danny Coates
441fe86186 attach delete-file handler only after upload 2017-08-07 11:47:09 -07:00
Lan Glad
f9283f5f6a Pontoon: Update Slovenian (sl) localization of Test Pilot: Firefox Send
Localization authors:
- Lan Glad <upwinxp@gmail.com>
2017-08-07 18:31:13 +00:00
Maykon Chagas
c8e0b696a6 Pontoon: Update Portuguese (pt-BR) localization of Test Pilot: Firefox Send
Localization authors:
- Maykon Chagas <mchagas@riseup.net>
2017-08-07 18:31:10 +00:00
Michael Köhler
cf5c64a3f8 Pontoon: Update German (de) localization of Test Pilot: Firefox Send
Localization authors:
- Michael Köhler <michael.koehler1@gmx.de>
2017-08-07 18:31:06 +00:00
Danny Coates
097ff19c5f Merge pull request #466 from mozilla/webpack
added webpack
2017-08-07 11:06:54 -07:00
Danny Coates
8767b9b6b0 Merge pull request #427 from gautamkrishnar/master
Extended system font list fixes:#408
2017-08-07 11:04:03 -07:00
Danny Coates
4ac7ac2b24 Merge pull request #448 from nskins/th-width
Migrate width attribute to CSS (Fixes #436)
2017-08-07 10:59:52 -07:00
Théo Chevalier
4cdce6c841 Pontoon: Update French (fr) localization of Test Pilot: Firefox Send
Localization authors:
- Théo Chevalier <theo.chevalier11@gmail.com>
2017-08-07 17:50:36 +00:00
Ton
763414c848 Pontoon: Update Dutch (nl) localization of Test Pilot: Firefox Send
Localization authors:
- Ton <tonnes.mb@gmail.com>
2017-08-07 17:50:33 +00:00
Danny Coates
9172af48fd added webpack 2017-08-07 10:33:41 -07:00
Tymur Faradzhev
14a4297db8 Pontoon: Update Ukrainian (uk) localization of Test Pilot: Firefox Send
Localization authors:
- Tymur Faradzhev <faradzhev.timur@gmail.com>
2017-08-07 17:30:49 +00:00
Rodrigo
a78475aff4 Pontoon: Update Portuguese (pt-PT) localization of Test Pilot: Firefox Send
Localization authors:
- Rodrigo <rodrigo.mcunha@hotmail.com>
2017-08-07 17:30:46 +00:00
Danny Coates
d2b57039bf Merge pull request #457 from mozilla/refactor-progress
factored out progress into progress.js
2017-08-07 09:51:29 -07:00
Pierre Neter
dd5be246d4 Pontoon: Update Vietnamese (vi) localization of Test Pilot: Firefox Send
Localization authors:
- hi <hi@duonganhtuan.com>
- Pierre Neter <pierreneter@gmail.com>
2017-08-07 12:10:33 +00:00
hi
779005845e Pontoon: Update Vietnamese (vi) localization of Test Pilot: Firefox Send
Localization authors:
- hi <hi@duonganhtuan.com>
- Pierre Neter <pierreneter@gmail.com>
2017-08-07 11:50:56 +00:00
hi
f3499326bd Pontoon: Update Vietnamese (vi) localization of Test Pilot: Firefox Send
Localization authors:
- hi <hi@duonganhtuan.com>
- Pierre Neter <pierreneter@gmail.com>
2017-08-07 11:30:52 +00:00
hi
fe10b131fc Pontoon: Update Vietnamese (vi) localization of Test Pilot: Firefox Send
Localization authors:
- hi <hi@duonganhtuan.com>
- Pierre Neter <pierreneter@gmail.com>
2017-08-07 11:11:18 +00:00
avelper
9b6b7aa998 Pontoon: Update Spanish (es-ES) localization of Test Pilot: Firefox Send
Localization authors:
- avelper <avelper@mozilla-hispano.org>
2017-08-07 10:10:59 +00:00
Slimane Amiri
e9d5d8ec11 Pontoon: Update Kabyle (kab) localization of Test Pilot: Firefox Send
Localization authors:
- Slimane Amiri <slimane.amiri@gmail.com>
2017-08-07 10:10:57 +00:00
Kohei Yoshino
73e39ad453 Pontoon: Update Japanese (ja) localization of Test Pilot: Firefox Send
Localization authors:
- Kohei Yoshino <kohei.yoshino@gmail.com>
2017-08-07 09:10:34 +00:00
Danny Coates
c91d24cd86 factored out progress into progress.js 2017-08-06 23:45:22 -07:00
Michal Stanke
1fc83aa902 Pontoon: Update Czech (cs) localization of Test Pilot: Firefox Send
Localization authors:
- Michal Stanke <mstanke@mozilla.cz>
2017-08-07 06:31:07 +00:00
Luna Jernberg
5ac013ca40 Pontoon: Update Swedish (sv-SE) localization of Test Pilot: Firefox Send
Localization authors:
- Luna Jernberg <bittin@cafe8bitar.se>
2017-08-06 18:31:42 +00:00
Danny Coates
6d17b86d28 Merge pull request #452 from mozilla/refactor-metrics
refactored metrics
2017-08-06 09:00:16 -07:00
Jamie
fcea981127 Cater for mobile and desktop
Fixes #421
2017-08-06 16:03:54 +01:00
siparon
bdd7044808 Pontoon: Update Hungarian (hu) localization of Test Pilot: Firefox Send
Localization authors:
- siparon <siparon@gmail.com>
2017-08-06 07:50:50 +00:00
Peter deHaan
96bea84a73 Merge pull request #455 from pdehaan/fix-es-cl-tr-locales
Add a few missing strings from es-CL and tr locales
2017-08-05 23:28:29 -07:00
Peter deHaan
9aef7df82c Add a few missing strings from es-CL and tr locales 2017-08-05 22:59:31 -07:00
Danny Coates
b0d36529a1 refactored metrics 2017-08-05 16:38:08 -07:00
Danny Coates
2a7099a7a2 Merge pull request #444 from Johann-S/patch-2
Chain jQuery calls, do not use events alias and store selectors
2017-08-05 16:32:49 -07:00
Maykon Chagas
4c069949f2 Pontoon: Update Portuguese (pt-BR) localization of Test Pilot: Firefox Send
Localization authors:
- Maykon Chagas <mchagas@riseup.net>
2017-08-05 22:10:39 +00:00
Maykon Chagas
699c97a9c0 Pontoon: Update Portuguese (pt-BR) localization of Test Pilot: Firefox Send
Localization authors:
- Maykon Chagas <mchagas@riseup.net>
2017-08-05 21:51:01 +00:00
Johann-S
3c640061f0 Chain jQuery calls, do not use events alias and store often used selectors 2017-08-05 22:31:57 +02:00
Jim Spentzos
bbd74efc2c Pontoon: Update Greek (el) localization of Test Pilot: Firefox Send
Localization authors:
- Jim Spentzos <jamesspentzos@hotmail.com>
- Giorgos S. <giorgos.skafidas@gmx.com>
2017-08-05 20:30:55 +00:00
Danny Coates
2dfbee090a Merge pull request #416 from mozilla/shim-webcrypto
WIP: use webcrypto-liner to support Safari 10
2017-08-05 10:09:09 -07:00
Danny Coates
a03b1b7a9a only _blank feedback link 2017-08-05 09:57:57 -07:00
Danny Coates
594b584500 formatting / links rel 2017-08-05 09:52:37 -07:00
Danny Coates
d74d339e4b Merge remote-tracking branch 'origin/master' into shim-webcrypto 2017-08-05 09:48:24 -07:00
Danny Coates
859554ce21 only _blank links while downloading. fixed safari link after download 2017-08-05 09:40:57 -07:00
Peter deHaan
703325f223 Merge pull request #451 from boopeshmahendran/AddRelNoopenerNoreferrer
Add rel noopener noreferrer to target='_blank' anchor elements (Fixes #439)
2017-08-05 09:17:10 -07:00
Peter deHaan
9a416e3e78 Merge pull request #449 from kenrick95/master
Add X-UA-Compatible meta tag
2017-08-05 09:14:39 -07:00
Maykon Chagas
8821403a9b Pontoon: Update Portuguese (pt-BR) localization of Test Pilot: Firefox Send
Localization authors:
- Maykon Chagas <mchagas@riseup.net>
2017-08-05 14:50:44 +00:00
alex_mayorga
4a841bf563 Pontoon: Update Spanish (es-MX) localization of Test Pilot: Firefox Send
Localization authors:
- alex_mayorga <alex_mayorga@yahoo.com>
2017-08-05 14:31:06 +00:00
Μιχάλης
4d6995536a Pontoon: Update Greek (el) localization of Test Pilot: Firefox Send
Localization authors:
- Μιχάλης <mikem132@protonmail.com>
2017-08-05 13:50:46 +00:00
Μιχάλης
6ef4e86029 Pontoon: Update Greek (el) localization of Test Pilot: Firefox Send
Localization authors:
- Giorgos S. <giorgos.skafidas@gmx.com>
- Μιχάλης <mikem132@protonmail.com>
2017-08-05 13:30:40 +00:00
Juraj Cigáň
2408c766ce Pontoon: Update Slovak (sk) localization of Test Pilot: Firefox Send
Localization authors:
- Juraj Cigáň <kusavica@gmail.com>
2017-08-05 11:10:31 +00:00
Amin Mahmudian
882e13bac6 Pontoon: Update Persian (fa) localization of Test Pilot: Firefox Send
Localization authors:
- Amin Mahmudian <amin.mahmudian@gmail.com>
2017-08-05 08:50:45 +00:00
Boopesh Mahendran
e48c2cf75b Add rel noopener noreferrer to target='_blank' anchor elements 2017-08-05 13:34:44 +05:30
gautamkrishnar
c8f7e60259 fixed lint errors 2017-08-05 12:59:00 +05:30
Danny Coates
432a39d313 Merge remote-tracking branch 'origin/master' into shim-webcrypto 2017-08-04 21:08:32 -07:00
kenrick95
59ed64698d Add X-UA-Compatible meta tag 2017-08-05 11:59:44 +08:00
Nicholas Skinsacos
6edfe5146c Migrate width attribute to CSS (Fixes #436) 2017-08-04 22:33:29 -04:00
Danny Coates
44ea0756ea Merge pull request #433 from pdehaan/issue-429
Prevent download button from being clicked multiple times
2017-08-04 15:46:56 -07:00
Danny Coates
02fc4d74db Merge remote-tracking branch 'origin/master' into shim-webcrypto 2017-08-04 14:47:40 -07:00
Danny Coates
0f77b6d86b Merge pull request #432 from pdehaan/issue-397
Add contributors script
2017-08-04 12:45:23 -07:00
Pin-guang Chen
ae2eb14fda Pontoon: Update Chinese (zh-TW) localization of Test Pilot: Firefox Send
Localization authors:
- Pin-guang Chen <petercpg@mail.moztw.org>
2017-08-04 18:31:09 +00:00
eljuno
455c4f5472 Pontoon: Update Indonesian (id) localization of Test Pilot: Firefox Send
Localization authors:
- eljuno <eljunotrie_anggoro@yahoo.co.id>
2017-08-04 17:31:10 +00:00
Gautam krishna.R
7335232680 fixed missing font 2017-08-04 22:49:03 +05:30
Peter deHaan
2f9372e8e0 Prevent download button from being clicked multiple times 2017-08-04 10:17:15 -07:00
Michael Wolf
80db158ee3 Pontoon: Update Sorbian, Upper (hsb) localization of Test Pilot: Firefox Send
Localization authors:
- Michael Wolf <milupo@sorbzilla.de>
2017-08-04 16:11:48 +00:00
Michael Wolf
6c18f4fb2c Pontoon: Update Sorbian, Lower (dsb) localization of Test Pilot: Firefox Send
Localization authors:
- Michael Wolf <milupo@sorbzilla.de>
2017-08-04 16:11:45 +00:00
Peter deHaan
f28444f4c6 Add contributors script 2017-08-04 09:10:59 -07:00
Marcelo Poli
93ac742a5e Pontoon: Update Spanish (es-AR) localization of Test Pilot: Firefox Send
Localization authors:
- Marcelo Poli <enzomatrix@gmail.com>
2017-08-04 15:31:33 +00:00
Erica
6dcbc19315 Merge pull request #409 from Johann-S/patch-1
Handle copy clipboard disabled
2017-08-04 10:32:24 -04:00
Ton
65df0fa9cf Pontoon: Update Dutch (nl) localization of Test Pilot: Firefox Send
Localization authors:
- Ton <tonnes.mb@gmail.com>
2017-08-04 12:31:11 +00:00
Kohei Yoshino
387e88907c Pontoon: Update Japanese (ja) localization of Test Pilot: Firefox Send
Localization authors:
- Kohei Yoshino <kohei.yoshino@gmail.com>
2017-08-04 10:10:46 +00:00
Gautam krishna.R
9253695f8d Extended system font list fixes:#408 2017-08-04 15:23:51 +05:30
Alexander Slovesnik
67635b9151 Pontoon: Update Russian (ru) localization of Test Pilot: Firefox Send
Localization authors:
- Alexander Slovesnik <unghost@mozilla-russia.org>
2017-08-04 09:10:33 +00:00
Johann-S
e0abfb5cf7 Handle copy clipboard disabled 2017-08-04 10:22:11 +02:00
Fjoerfoks
f1de6a14da Pontoon: Update Frisian (fy-NL) localization of Test Pilot: Firefox Send
Localization authors:
- Fjoerfoks <fryskefirefox@gmail.com>
2017-08-04 07:30:43 +00:00
Sairam Raavi
38052c1b85 Pontoon: Update Telugu (te) localization of Test Pilot: Firefox Send
Localization authors:
- Sairam Raavi <sairam@riseup.net>
2017-08-04 05:50:36 +00:00
Sahithi
5847faf4e2 Pontoon: Update Telugu (te) localization of Test Pilot: Firefox Send
Localization authors:
- Sairam Raavi <sairam@riseup.net>
- Sahithi <sahithi.thinker@gmail.com>
- నితిన్ <sainithin95@gmail.com>
2017-08-04 05:31:26 +00:00
Francesco Lodolo
0c1c8178f5 Pontoon: Update Italian (it) localization of Test Pilot: Firefox Send
Localization authors:
- Francesco Lodolo <francesco.lodolo@mozillaitalia.org>
2017-08-04 05:31:24 +00:00
Sahithi
86fbd2a4b5 Pontoon: Update Telugu (te) localization of Test Pilot: Firefox Send
Localization authors:
- Sairam Raavi <sairam@riseup.net>
- Sahithi <sahithi.thinker@gmail.com>
2017-08-04 05:10:53 +00:00
Danny Coates
8cfb45944c pruned server logs 2017-08-03 21:47:03 -07:00
Tymur Faradzhev
0289409c9c Pontoon: Update Ukrainian (uk) localization of Test Pilot: Firefox Send
Localization authors:
- Tymur Faradzhev <faradzhev.timur@gmail.com>
2017-08-04 04:10:53 +00:00
Danny Coates
b93a33eba4 an ios friendly copy 2017-08-03 21:06:15 -07:00
Danny Coates
fb41a40128 use webcrypto-liner to support Safari 10 2017-08-03 19:13:38 -07:00
ravmn
e18fda91fe Pontoon: Update Spanish (es-CL) localization of Test Pilot: Firefox Send
Localization authors:
- ravmn <ravmn@ravmn.cl>
2017-08-04 00:31:52 +00:00
YFdyh000
b077635427 Pontoon: Update Chinese (zh-CN) localization of Test Pilot: Firefox Send
Localization authors:
- YFdyh000 <yfdyh000@gmail.com>
2017-08-04 00:31:49 +00:00
Håvar Henriksen
4d4098b7c9 Pontoon: Update Norwegian Bokmål (nb-NO) localization of Test Pilot: Firefox Send
Localization authors:
- Håvar Henriksen <havar@firefox.no>
2017-08-03 23:31:13 +00:00
Emin Mastizada
9e4838d121 Pontoon: Update Azerbaijani (az) localization of Test Pilot: Firefox Send
Localization authors:
- Emin Mastizada <emin@mastizada.com>
2017-08-03 23:31:11 +00:00
84 changed files with 8787 additions and 1745 deletions

View File

@@ -6,3 +6,7 @@ test
scripts scripts
docs docs
firefox firefox
public
views
webpack
frontend

14
.editorconfig Normal file
View File

@@ -0,0 +1,14 @@
root = true
[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
[*.{js,html,yml,json,handlebars}]
indent_style = space
indent_size = 2
[*.toml]
indent_style = space
indent_size = 4

6
.gitignore vendored
View File

@@ -1,10 +1,6 @@
.DS_Store .DS_Store
dist
node_modules node_modules
public/upload.js
public/download.js
public/version.json
public/l20n.min.js
public/polyfill.min.js
static/* static/*
!static/info.txt !static/info.txt
test/frontend/bundle.js test/frontend/bundle.js

View File

@@ -1,6 +1,11 @@
extends: stylelint-config-standard extends: stylelint-config-standard
plugins:
- stylelint-no-unsupported-browser-features
rules: rules:
plugin/no-unsupported-browser-features: [true, {severity: warning}]
color-hex-case: lower color-hex-case: lower
declaration-colon-newline-after: null declaration-colon-newline-after: null
selector-list-comma-newline-after: null selector-list-comma-newline-after: null

78
CONTRIBUTORS Normal file
View File

@@ -0,0 +1,78 @@
Abhinav Adduri
Alexander Slovesnik
Amin Mahmudian
Andreas Pettersson
Balázs Meskó
Bjørn I
Boopesh Mahendran
Chuck Harmston
Cynthia Pereira
Daniel Thorn
Daniela Arcese
Danny Coates
Emin Mastizada
Erica
Erica Wright
Fjoerfoks
Francesco Lodolo
Francesco Lodolo [:flod]
Gautam krishna.R
Håvar Henriksen
Jim Spentzos
Johann-S
John Gruen
Jordi Serratosa
Juraj Cigáň
Kohei Yoshino
Lan Glad
Luna Jernberg
Marcelo Poli
Marco Aurélio
Mark Liang
Matjaž Horvat
Maykon Chagas
Michael Köhler
Michael Wolf
Michal Stanke
Michal Vašíček
Moḥend Belqasem
Nicholas Skinsacos
Peter deHaan
Pierre Neter
Pin-guang Chen
Rhoslyn Prys
Rizky Ariestiyansyah
Roberto Alvarado
Rodrigo
Rok Žerdin
Sahithi
Sairam Raavi
Sandro
Selim Şumlu
Slimane Amiri
Théo Chevalier
Tomáš Zelina
Ton
Tymur Faradzhev
Victor Bychek
Weihang Lo
Wil Clouser
YFdyh000
You-Wen Liang (Mark)
alex_mayorga
ariestiyansyah
avelper
dgadelha
ehuggett
eljuno
erdem cobanoglu
gautamkrishnar
goofy
hi
kenrick95
manxmensch
ravmn
siparon
xcffl
Μιχάλης
Марко Костић (Marko Kostić)

5
browserslist Normal file
View File

@@ -0,0 +1,5 @@
last 2 chrome versions
last 2 firefox versions
firefox esr
ie >= 9
safari >= 9

View File

@@ -16,7 +16,6 @@ deployment:
latest: latest:
branch: master branch: master
commands: commands:
- npm run build
- docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
- docker build -t mozilla/send:latest . - docker build -t mozilla/send:latest .
- docker push mozilla/send:latest - docker push mozilla/send:latest
@@ -24,14 +23,13 @@ deployment:
tag: /.*/ tag: /.*/
owner: mozilla owner: mozilla
commands: commands:
- npm run build
- docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
- docker build -t mozilla/send:$CIRCLE_TAG . - docker build -t mozilla/send:$CIRCLE_TAG .
- docker push mozilla/send:$CIRCLE_TAG - docker push mozilla/send:$CIRCLE_TAG
test: test:
override: override:
- npm run build:version - npm run build
- npm run lint - npm run lint
- npm test - npm test
- nsp check - nsp check

View File

@@ -8,5 +8,6 @@ services:
- "1443:1443" - "1443:1443"
environment: environment:
- REDIS_HOST=redis - REDIS_HOST=redis
- NODE_ENV=production
redis: redis:
image: redis:alpine image: redis:alpine

View File

@@ -1,3 +1,9 @@
env: env:
browser: true browser: true
jquery: true node: false
parserOptions:
sourceType: module
rules:
node/no-unsupported-features: off

View File

@@ -1,35 +1,20 @@
window.Raven = require('raven-js'); import Raven from 'raven-js';
import { unsupported } from './metrics';
if (navigator.doNotTrack !== '1' && window.RAVEN_CONFIG) { if (navigator.doNotTrack !== '1' && window.RAVEN_CONFIG) {
window.Raven.config(window.SENTRY_ID, window.RAVEN_CONFIG).install(); Raven.config(window.SENTRY_ID, window.RAVEN_CONFIG).install();
} }
const testPilotGA = require('testpilot-ga');
const { gcmCompliant, sendEvent } = require('./utils');
window.analytics = new testPilotGA({
an: 'Firefox Send',
ds: 'web',
tid: window.GOOGLE_ANALYTICS_ID
});
const isSender = !location.pathname.includes('/download');
const ec = isSender ? 'sender' : 'recipient';
const ua = navigator.userAgent.toLowerCase(); const ua = navigator.userAgent.toLowerCase();
gcmCompliant().catch(err => {
sendEvent(ec, 'unsupported', {
cd6: err
}).then(() => {
location.replace('/unsupported/gcm');
});
});
if ( if (
ua.indexOf('firefox') > -1 && ua.indexOf('firefox') > -1 &&
parseInt(ua.match(/firefox\/*([^\n\r]*)\./)[1], 10) <= 49 parseInt(ua.match(/firefox\/*([^\n\r]*)\./)[1], 10) <= 49
) { ) {
sendEvent(ec, 'unsupported', { unsupported({
cd6: new Error('Firefox is outdated.') err: new Error('Firefox is outdated.')
}).then(() => { }).then(() => {
location.replace('/unsupported/outdated'); location.replace('/unsupported/outdated');
}); });
} }
export { Raven };

View File

@@ -1,181 +1,119 @@
require('./common'); import { Raven } from './common';
const FileReceiver = require('./fileReceiver'); import FileReceiver from './fileReceiver';
const { notify, findMetric, sendEvent } = require('./utils'); import { bytes, notify, gcmCompliant } from './utils';
const bytes = require('bytes'); import Storage from './storage';
const Storage = require('./storage'); import * as links from './links';
const storage = new Storage(localStorage); import * as metrics from './metrics';
import * as progress from './progress';
const $ = require('jquery'); const storage = new Storage();
require('jquery-circle-progress'); function onUnload(size) {
metrics.cancelledDownload({ size });
}
const Raven = window.Raven; async function download() {
const downloadBtn = document.getElementById('download-btn');
const downloadPanel = document.getElementById('download-page-one');
const progressPanel = document.getElementById('download-progress');
const file = document.getElementById('dl-file');
const size = Number(file.getAttribute('data-size'));
const ttl = Number(file.getAttribute('data-ttl'));
const unloadHandler = onUnload.bind(null, size);
const startTime = Date.now();
const fileReceiver = new FileReceiver(
'/assets' + location.pathname.slice(0, -1),
location.hash.slice(1)
);
$(document).ready(function() { downloadBtn.disabled = true;
//link back to homepage downloadPanel.hidden = true;
$('.send-new').attr('href', window.location.origin); progressPanel.hidden = false;
metrics.startedDownload({ size, ttl });
links.setOpenInNewTab(true);
window.addEventListener('unload', unloadHandler);
$('.send-new').click(function() { fileReceiver.on('progress', data => {
sendEvent('recipient', 'restarted', { progress.setProgress({ complete: data[0], total: data[1] });
cd2: 'completed'
});
}); });
$('.legal-links a, .social-links a, #dl-firefox').click(function(target) { let downloadEnd;
const metric = findMetric(target.currentTarget.href); fileReceiver.on('decrypting', () => {
// record exited event by recipient downloadEnd = Date.now();
sendEvent('recipient', 'exited', { window.removeEventListener('unload', unloadHandler);
cd3: metric fileReceiver.removeAllListeners('progress');
}); document.l10n.formatValue('decryptingFile').then(progress.setText);
}); });
const filename = $('#dl-filename').text(); try {
const bytelength = Number($('#dl-bytelength').text()); const file = await fileReceiver.download();
const timeToExpiry = Number($('#dl-ttl').text()); const endTime = Date.now();
const time = endTime - startTime;
const downloadTime = endTime - downloadEnd;
const speed = size / (downloadTime / 1000);
//initiate progress bar links.setOpenInNewTab(false);
$('#dl-progress').circleProgress({
value: 0.0,
startAngle: -Math.PI / 2,
fill: '#3B9DFF',
size: 158,
animation: { duration: 300 }
});
$('#download-btn').click(download);
function download() {
storage.totalDownloads += 1; storage.totalDownloads += 1;
metrics.completedDownload({ size, time, speed });
const fileReceiver = new FileReceiver(); progress.setText(' ');
const unexpiredFiles = storage.numFiles; document.l10n
.formatValues('downloadNotification', 'downloadFinish')
fileReceiver.on('progress', progress => { .then(translated => {
window.onunload = function() { notify(translated[0]);
storage.referrer = 'cancelled-download'; document.getElementById('dl-title').textContent = translated[1];
// record download-stopped (cancelled by tab close or reload) document.querySelector('#download-progress .description').textContent =
sendEvent('recipient', 'download-stopped', { ' ';
cm1: bytelength,
cm5: storage.totalUploads,
cm6: unexpiredFiles,
cm7: storage.totalDownloads,
cd2: 'cancelled'
});
};
$('#download-page-one').attr('hidden', true);
$('#download-progress').removeAttr('hidden');
const percent = progress[0] / progress[1];
// update progress bar
$('#dl-progress').circleProgress('value', percent);
$('.percent-number').text(`${Math.floor(percent * 100)}`);
$('.progress-text').text(
`${filename} (${bytes(progress[0], {
decimalPlaces: 1,
fixedDecimals: true
})} of ${bytes(progress[1], { decimalPlaces: 1 })})`
);
});
let downloadEnd;
fileReceiver.on('decrypting', isStillDecrypting => {
// The file is being decrypted
if (isStillDecrypting) {
fileReceiver.removeAllListeners('progress');
window.onunload = null;
document.l10n.formatValue('decryptingFile').then(decryptingFile => {
$('.progress-text').text(decryptingFile);
});
} else {
downloadEnd = Date.now();
}
});
fileReceiver.on('hashing', isStillHashing => {
// The file is being hashed to make sure a malicious user hasn't tampered with it
if (isStillHashing) {
document.l10n.formatValue('verifyingFile').then(verifyingFile => {
$('.progress-text').text(verifyingFile);
});
} else {
$('.progress-text').text(' ');
document.l10n
.formatValues('downloadNotification', 'downloadFinish')
.then(translated => {
notify(translated[0]);
$('.title').text(translated[1]);
});
}
});
const startTime = Date.now();
// record download-started by recipient
sendEvent('recipient', 'download-started', {
cm1: bytelength,
cm4: timeToExpiry,
cm5: storage.totalUploads,
cm6: unexpiredFiles,
cm7: storage.totalDownloads
});
fileReceiver
.download()
.catch(err => {
// record download-stopped (errored) by recipient
sendEvent('recipient', 'download-stopped', {
cm1: bytelength,
cm5: storage.totalUploads,
cm6: unexpiredFiles,
cm7: storage.totalDownloads,
cd2: 'errored',
cd6: err
});
if (err.message === 'notfound') {
location.reload();
} else {
document.l10n.formatValue('errorPageHeader').then(translated => {
$('.title').text(translated);
});
$('#download-btn').attr('hidden', true);
$('#expired-img').removeAttr('hidden');
}
throw err;
})
.then(([decrypted, fname]) => {
const endTime = Date.now();
const totalTime = endTime - startTime;
const downloadTime = endTime - downloadEnd;
const downloadSpeed = bytelength / (downloadTime / 1000);
storage.referrer = 'completed-download';
// record download-stopped (completed) by recipient
sendEvent('recipient', 'download-stopped', {
cm1: bytelength,
cm2: totalTime,
cm3: downloadSpeed,
cm5: storage.totalUploads,
cm6: unexpiredFiles,
cm7: storage.totalDownloads,
cd2: 'completed'
});
const dataView = new DataView(decrypted);
const blob = new Blob([dataView]);
const downloadUrl = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = downloadUrl;
if (window.navigator.msSaveBlob) {
// if we are in microsoft edge or IE
window.navigator.msSaveBlob(blob, fname);
return;
}
a.download = fname;
document.body.appendChild(a);
a.click();
})
.catch(err => {
Raven.captureException(err);
return Promise.reject(err);
}); });
const dataView = new DataView(file.plaintext);
const blob = new Blob([dataView], { type: file.type });
const downloadUrl = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = downloadUrl;
if (window.navigator.msSaveBlob) {
window.navigator.msSaveBlob(blob, file.name);
return;
}
a.download = file.name;
document.body.appendChild(a);
a.click();
URL.revokeObjectURL(downloadUrl);
} catch (err) {
metrics.stoppedDownload({ size, err });
if (err.message === 'notfound') {
location.reload();
} else {
progressPanel.hidden = true;
downloadPanel.hidden = true;
document.getElementById('upload-error').hidden = false;
}
Raven.captureException(err);
} }
}
document.addEventListener('DOMContentLoaded', function() {
const file = document.getElementById('dl-file');
const filename = file.getAttribute('data-filename');
const b = Number(file.getAttribute('data-size'));
const size = bytes(b);
document.l10n.formatValue('downloadFileSize', { size }).then(str => {
document.getElementById('dl-filesize').textContent = str;
});
document.l10n
.formatValue('downloadingPageProgress', { filename, size })
.then(str => {
document.getElementById('dl-title').textContent = str;
});
gcmCompliant()
.then(() => {
document
.getElementById('download-btn')
.addEventListener('click', download);
})
.catch(err => {
metrics.unsupported({ err }).then(() => {
location.replace('/unsupported/gcm');
});
});
}); });

163
frontend/src/fileList.js Normal file
View File

@@ -0,0 +1,163 @@
import FileSender from './fileSender';
import Storage from './storage';
import * as metrics from './metrics';
import { allowedCopy, copyToClipboard, ONE_DAY_IN_MS } from './utils';
import bel from 'bel';
import copyImg from '../../public/resources/copy-16.svg';
import closeImg from '../../public/resources/close-16.svg';
const HOUR = 1000 * 60 * 60;
const storage = new Storage();
let fileList = null;
document.addEventListener('DOMContentLoaded', function() {
fileList = document.getElementById('file-list');
toggleHeader();
Promise.all(
storage.files.map(file => {
const id = file.fileId;
return checkExistence(id).then(exists => {
if (exists) {
addFile(storage.getFileById(id));
} else {
storage.remove(id);
}
});
})
)
.catch(err => console.error(err))
.then(toggleHeader);
});
function toggleHeader() {
fileList.hidden = storage.files.length === 0;
}
function timeLeft(milliseconds) {
const minutes = Math.floor(milliseconds / 1000 / 60);
const hours = Math.floor(minutes / 60);
const seconds = Math.floor(milliseconds / 1000 % 60);
if (hours >= 1) {
return `${hours}h ${minutes % 60}m`;
} else if (hours === 0) {
return `${minutes}m ${seconds}s`;
}
return 'Expired';
}
function addFile(file) {
if (!file) {
return;
}
file.creationDate = new Date(file.creationDate);
const url = `${file.url}#${file.secretKey}`;
const future = new Date();
future.setTime(file.creationDate.getTime() + file.expiry);
const countdown = future.getTime() - Date.now();
const row = bel`
<tr>
<td>${file.name}</td>
<td>
<span class="icon-docs" data-l10n-id="copyUrlHover"></span>
<img onclick=${copyClick} src="${copyImg}" class="icon-copy" data-l10n-id="copyUrlHover">
<span data-l10n-id="copiedUrl" class="text-copied" hidden="true"></span>
</td>
<td>${timeLeft(countdown)}</td>
<td>
<span class="icon-cancel-1" data-l10n-id="deleteButtonHover" title="Delete"></span>
<img onclick=${showPopup} src="${closeImg}" class="icon-delete" data-l10n-id="deleteButtonHover" title="Delete">
<div class="popup">
<div class="popuptext" onclick=${stopProp} onblur=${cancel} tabindex="-1">
<div class="popup-message" data-l10n-id="deletePopupText"></div>
<div class="popup-action">
<span class="popup-no" onclick=${cancel} data-l10n-id="deletePopupCancel"></span>
<span class="popup-yes" onclick=${deleteFile} data-l10n-id="deletePopupYes"></span>
</div>
</div>
</div>
</td>
</tr>
`;
const popup = row.querySelector('.popuptext');
const timeCol = row.querySelectorAll('td')[2];
if (!allowedCopy()) {
row.querySelector('.icon-copy').disabled = true;
}
fileList.querySelector('tbody').appendChild(row);
toggleHeader();
poll();
function copyClick(e) {
metrics.copiedLink({ location: 'upload-list' });
copyToClipboard(url);
const icon = e.target;
const text = e.target.nextSibling;
icon.hidden = true;
text.hidden = false;
setTimeout(() => {
icon.hidden = false;
text.hidden = true;
}, 500);
}
function poll() {
const countdown = future.getTime() - Date.now();
if (countdown <= 0) {
storage.remove(file.fileId);
row.parentNode.removeChild(row);
toggleHeader();
}
timeCol.textContent = timeLeft(countdown);
setTimeout(poll, countdown >= HOUR ? 60000 : 1000);
}
function deleteFile() {
FileSender.delete(file.fileId, file.deleteToken);
const ttl = ONE_DAY_IN_MS - (Date.now() - file.creationDate.getTime());
metrics.deletedUpload({
size: file.size,
time: file.totalTime,
speed: file.uploadSpeed,
type: file.typeOfUpload,
location: 'upload-list',
ttl
});
row.parentNode.removeChild(row);
storage.remove(file.fileId);
toggleHeader();
}
function showPopup() {
popup.classList.add('show');
popup.focus();
}
function cancel(e) {
e.stopPropagation();
popup.classList.remove('show');
}
function stopProp(e) {
e.stopPropagation();
}
}
async function checkExistence(id) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
resolve(xhr.status === 200);
}
};
xhr.onerror = reject;
xhr.ontimeout = reject;
xhr.open('get', '/exists/' + id);
xhr.timeout = 2000;
xhr.send();
});
}
export { addFile };

View File

@@ -1,107 +1,81 @@
const EventEmitter = require('events'); import EventEmitter from 'events';
const { hexToArray } = require('./utils'); import { hexToArray } from './utils';
class FileReceiver extends EventEmitter { export default class FileReceiver extends EventEmitter {
constructor() { constructor(url, k) {
super(); super();
this.key = window.crypto.subtle.importKey(
'jwk',
{
k,
kty: 'oct',
alg: 'A128GCM',
ext: true
},
{
name: 'AES-GCM'
},
false,
['decrypt']
);
this.url = url;
} }
download() { downloadFile() {
return window.crypto.subtle return new Promise((resolve, reject) => {
.importKey( const xhr = new XMLHttpRequest();
'jwk',
{
kty: 'oct',
k: location.hash.slice(1),
alg: 'A128GCM',
ext: true
},
{
name: 'AES-GCM'
},
true,
['encrypt', 'decrypt']
)
.then(key => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onprogress = event => { xhr.onprogress = event => {
if (event.lengthComputable && event.target.status !== 404) { if (event.lengthComputable && event.target.status !== 404) {
this.emit('progress', [event.loaded, event.total]); this.emit('progress', [event.loaded, event.total]);
} }
}; };
xhr.onload = function(event) { xhr.onload = function(event) {
if (xhr.status === 404) { if (xhr.status === 404) {
reject(new Error('notfound')); reject(new Error('notfound'));
return; return;
} }
const blob = new Blob([this.response]); const blob = new Blob([this.response]);
const fileReader = new FileReader(); const type = xhr.getResponseHeader('Content-Type');
fileReader.onload = function() { const meta = JSON.parse(xhr.getResponseHeader('X-File-Metadata'));
const meta = JSON.parse(xhr.getResponseHeader('X-File-Metadata')); const fileReader = new FileReader();
resolve([ fileReader.onload = function() {
{ resolve({
data: this.result, data: this.result,
aad: meta.aad, name: meta.filename,
filename: meta.filename, type,
iv: meta.id iv: meta.id
},
key
]);
};
fileReader.readAsArrayBuffer(blob);
};
xhr.open('get', '/assets' + location.pathname.slice(0, -1), true);
xhr.responseType = 'blob';
xhr.send();
});
})
.then(([fdata, key]) => {
this.emit('decrypting', true);
return Promise.all([
window.crypto.subtle
.decrypt(
{
name: 'AES-GCM',
iv: hexToArray(fdata.iv),
additionalData: hexToArray(fdata.aad),
tagLength: 128
},
key,
fdata.data
)
.then(decrypted => {
this.emit('decrypting', false);
return Promise.resolve(decrypted);
}),
fdata.filename,
hexToArray(fdata.aad)
]);
})
.then(([decrypted, fname, proposedHash]) => {
this.emit('hashing', true);
return window.crypto.subtle
.digest('SHA-256', decrypted)
.then(calculatedHash => {
this.emit('hashing', false);
const integrity =
new Uint8Array(calculatedHash).toString() ===
proposedHash.toString();
if (!integrity) {
this.emit('unsafe', true);
return Promise.reject();
} else {
this.emit('safe', true);
return Promise.all([decrypted, decodeURIComponent(fname)]);
}
}); });
}); };
fileReader.readAsArrayBuffer(blob);
};
xhr.open('get', this.url);
xhr.responseType = 'blob';
xhr.send();
});
}
async download() {
const key = await this.key;
const file = await this.downloadFile();
this.emit('decrypting');
const plaintext = await window.crypto.subtle.decrypt(
{
name: 'AES-GCM',
iv: hexToArray(file.iv),
tagLength: 128
},
key,
file.data
);
return {
plaintext,
name: decodeURIComponent(file.name),
type: file.type
};
} }
} }
module.exports = FileReceiver;

View File

@@ -1,12 +1,20 @@
const EventEmitter = require('events'); import EventEmitter from 'events';
const { arrayToHex } = require('./utils'); import { arrayToHex } from './utils';
class FileSender extends EventEmitter { export default class FileSender extends EventEmitter {
constructor(file) { constructor(file) {
super(); super();
this.file = file; this.file = file;
this.iv = window.crypto.getRandomValues(new Uint8Array(12)); this.iv = window.crypto.getRandomValues(new Uint8Array(12));
this.uploadXHR = new XMLHttpRequest(); this.uploadXHR = new XMLHttpRequest();
this.key = window.crypto.subtle.generateKey(
{
name: 'AES-GCM',
length: 128
},
true,
['encrypt']
);
} }
static delete(fileId, token) { static delete(fileId, token) {
@@ -32,106 +40,79 @@ class FileSender extends EventEmitter {
this.uploadXHR.abort(); this.uploadXHR.abort();
} }
upload() { readFile() {
const self = this; return new Promise((resolve, reject) => {
self.emit('loading', true); const reader = new FileReader();
return Promise.all([ reader.readAsArrayBuffer(this.file);
window.crypto.subtle.generateKey( reader.onload = function(event) {
{ const plaintext = new Uint8Array(this.result);
name: 'AES-GCM', resolve(plaintext);
length: 128 };
}, reader.onerror = function(err) {
true, reject(err);
['encrypt', 'decrypt'] };
), });
new Promise((resolve, reject) => { }
const reader = new FileReader();
reader.readAsArrayBuffer(this.file);
reader.onload = function(event) {
self.emit('loading', false);
self.emit('hashing', true);
const plaintext = new Uint8Array(this.result);
window.crypto.subtle.digest('SHA-256', plaintext).then(hash => {
self.emit('hashing', false);
self.emit('encrypting', true);
resolve({ plaintext: plaintext, hash: new Uint8Array(hash) });
});
};
reader.onerror = function(err) {
reject(err);
};
})
])
.then(([secretKey, file]) => {
return Promise.all([
window.crypto.subtle
.encrypt(
{
name: 'AES-GCM',
iv: this.iv,
additionalData: file.hash,
tagLength: 128
},
secretKey,
file.plaintext
)
.then(encrypted => {
self.emit('encrypting', false);
return new Promise((resolve, reject) => {
resolve(encrypted);
});
}),
window.crypto.subtle.exportKey('jwk', secretKey),
new Promise((resolve, reject) => {
resolve(file.hash);
})
]);
})
.then(([encrypted, keydata, hash]) => {
return new Promise((resolve, reject) => {
const file = this.file;
const fileId = arrayToHex(this.iv);
const dataView = new DataView(encrypted);
const blob = new Blob([dataView], { type: file.type });
const fd = new FormData();
fd.append('data', blob, file.name);
const xhr = self.uploadXHR; uploadFile(encrypted, keydata) {
return new Promise((resolve, reject) => {
const file = this.file;
const fileId = arrayToHex(this.iv);
const dataView = new DataView(encrypted);
const blob = new Blob([dataView], { type: file.type });
const fd = new FormData();
fd.append('data', blob, file.name);
xhr.upload.addEventListener('progress', e => { const xhr = this.uploadXHR;
if (e.lengthComputable) {
self.emit('progress', [e.loaded, e.total]);
}
});
xhr.onreadystatechange = () => { xhr.upload.addEventListener('progress', e => {
if (xhr.readyState === XMLHttpRequest.DONE) { if (e.lengthComputable) {
if (xhr.status === 200) { this.emit('progress', [e.loaded, e.total]);
const responseObj = JSON.parse(xhr.responseText); }
return resolve({
url: responseObj.url,
fileId: responseObj.id,
secretKey: keydata.k,
deleteToken: responseObj.delete
});
}
reject(xhr.status);
}
};
xhr.open('post', '/upload', true);
xhr.setRequestHeader(
'X-File-Metadata',
JSON.stringify({
aad: arrayToHex(hash),
id: fileId,
filename: encodeURIComponent(file.name)
})
);
xhr.send(fd);
});
}); });
xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
const responseObj = JSON.parse(xhr.responseText);
return resolve({
url: responseObj.url,
fileId: responseObj.id,
secretKey: keydata.k,
deleteToken: responseObj.delete
});
}
reject(xhr.status);
}
};
xhr.open('post', '/upload', true);
xhr.setRequestHeader(
'X-File-Metadata',
JSON.stringify({
id: fileId,
filename: encodeURIComponent(file.name)
})
);
xhr.send(fd);
});
}
async upload() {
this.emit('loading');
const key = await this.key;
const plaintext = await this.readFile();
this.emit('encrypting');
const encrypted = await window.crypto.subtle.encrypt(
{
name: 'AES-GCM',
iv: this.iv,
tagLength: 128
},
key,
plaintext
);
const keydata = await window.crypto.subtle.exportKey('jwk', key);
return this.uploadFile(encrypted, keydata);
} }
} }
module.exports = FileSender;

21
frontend/src/links.js Normal file
View File

@@ -0,0 +1,21 @@
let links = [];
document.addEventListener('DOMContentLoaded', function() {
links = Array.from(document.querySelectorAll('a:not([target])'));
});
function setOpenInNewTab(bool) {
if (bool === false) {
links.forEach(l => {
l.removeAttribute('target');
l.removeAttribute('rel');
});
} else {
links.forEach(l => {
l.setAttribute('target', '_blank');
l.setAttribute('rel', 'noopener noreferrer');
});
}
}
export { setOpenInNewTab };

View File

@@ -1,8 +1,8 @@
/*** index.html ***/ /*** index.html ***/
html { html {
background: url('resources/send_bg.svg'); background: url('../../public/resources/send_bg.svg');
font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', Helvetica, font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'segoe ui',
Arial, sans-serif; 'helvetica neue', helvetica, ubuntu, roboto, noto, arial, sans-serif;
font-weight: 200; font-weight: 200;
background-size: 110%; background-size: 110%;
background-repeat: no-repeat; background-repeat: no-repeat;
@@ -13,6 +13,8 @@ html {
} }
body { body {
font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'segoe ui',
'helvetica neue', helvetica, ubuntu, roboto, noto, arial, sans-serif;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin: 0; margin: 0;
@@ -20,6 +22,16 @@ body {
position: relative; position: relative;
} }
#progress circle {
stroke: #eee;
stroke-width: 0.75em;
}
#progress #bar {
transition: stroke-dashoffset 300ms linear;
stroke: #3b9dff;
}
.header { .header {
align-items: flex-start; align-items: flex-start;
box-sizing: border-box; box-sizing: border-box;
@@ -77,7 +89,7 @@ body {
.feedback { .feedback {
background-color: #0297f8; background-color: #0297f8;
background-image: url('resources/feedback.svg'); background-image: url('../../public/resources/feedback.svg');
background-position: 2px 4px; background-position: 2px 4px;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 18px; background-size: 18px;
@@ -136,6 +148,10 @@ a {
text-decoration: none; text-decoration: none;
} }
.btn {
font-weight: 500;
}
/** page-one **/ /** page-one **/
.title { .title {
@@ -206,12 +222,13 @@ a {
border-radius: 5px; border-radius: 5px;
font-size: 15px; font-size: 15px;
color: #fff; color: #fff;
width: 240px; min-width: 240px;
height: 44px; height: 44px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
cursor: pointer; cursor: pointer;
padding: 0 10px;
} }
#browse:hover { #browse:hover {
@@ -266,12 +283,37 @@ tbody {
table-layout: fixed; table-layout: fixed;
} }
#uploaded-file {
width: 35%;
}
#copy-file-list {
width: 25%;
}
#expiry-file-list {
width: 21%;
}
#delete-file-list {
width: 12%;
}
.icon-delete, .icon-delete,
.icon-copy, .icon-copy,
.icon-check { .icon-check {
cursor: pointer; cursor: pointer;
} }
.icon-copy[disabled="disabled"] {
pointer-events: none;
opacity: 0.3;
}
.text-copied {
color: #0a8dff;
}
/* Popup container */ /* Popup container */
.popup { .popup {
position: absolute; position: absolute;
@@ -392,7 +434,7 @@ tbody {
position: absolute; position: absolute;
letter-spacing: -0.78px; letter-spacing: -0.78px;
font-family: 'Segoe UI', 'SF Pro Text', sans-serif; font-family: 'Segoe UI', 'SF Pro Text', sans-serif;
top: 53px; top: 58px;
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
-moz-user-select: none; -moz-user-select: none;
@@ -504,6 +546,7 @@ tbody {
background: #05a700; background: #05a700;
border: 1px solid #05a700; border: 1px solid #05a700;
cursor: auto; cursor: auto;
opacity: 0.3;
} }
#delete-file { #delete-file {
@@ -620,7 +663,6 @@ tbody {
background: #0297f8; background: #0297f8;
border: 1px solid #0297f8; border: 1px solid #0297f8;
border-radius: 5px; border-radius: 5px;
font-weight: 300;
cursor: pointer; cursor: pointer;
} }

249
frontend/src/metrics.js Normal file
View File

@@ -0,0 +1,249 @@
import testPilotGA from 'testpilot-ga/src/TestPilotGA';
import Storage from './storage';
const storage = new Storage();
let hasLocalStorage = false;
try {
hasLocalStorage = !!localStorage;
} catch (e) {
// don't care
}
const analytics = new testPilotGA({
an: 'Firefox Send',
ds: 'web',
tid: window.GOOGLE_ANALYTICS_ID
});
const category = location.pathname.includes('/download')
? 'recipient'
: 'sender';
document.addEventListener('DOMContentLoaded', function() {
addExitHandlers();
addRestartHandlers();
});
function sendEvent() {
return (
hasLocalStorage &&
analytics.sendEvent.apply(analytics, arguments).catch(() => 0)
);
}
function urlToMetric(url) {
switch (url) {
case 'https://www.mozilla.org/':
return 'mozilla';
case 'https://www.mozilla.org/about/legal':
return 'legal';
case 'https://testpilot.firefox.com/about':
return 'about';
case 'https://testpilot.firefox.com/privacy':
return 'privacy';
case 'https://testpilot.firefox.com/terms':
return 'terms';
case 'https://www.mozilla.org/privacy/websites/#cookies':
return 'cookies';
case 'https://github.com/mozilla/send':
return 'github';
case 'https://twitter.com/FxTestPilot':
return 'twitter';
case 'https://www.mozilla.org/firefox/new/?scene=2':
return 'download-firefox';
case 'https://qsurvey.mozilla.com/s3/txp-firefox-send':
return 'survey';
case 'https://testpilot.firefox.com/':
case 'https://testpilot.firefox.com/experiments/send':
return 'testpilot';
default:
return 'other';
}
}
function setReferrer(state) {
if (category === 'sender') {
if (state) {
storage.referrer = `${state}-upload`;
}
} else if (category === 'recipient') {
if (state) {
storage.referrer = `${state}-download`;
}
}
}
function externalReferrer() {
if (/^https:\/\/testpilot\.firefox\.com/.test(document.referrer)) {
return 'testpilot';
}
return 'external';
}
function takeReferrer() {
const referrer = storage.referrer || externalReferrer();
storage.referrer = null;
return referrer;
}
function startedUpload(params) {
return sendEvent(category, 'upload-started', {
cm1: params.size,
cm5: storage.totalUploads,
cm6: storage.numFiles + 1,
cm7: storage.totalDownloads,
cd1: params.type,
cd5: takeReferrer()
});
}
function cancelledUpload(params) {
setReferrer('cancelled');
return sendEvent(category, 'upload-stopped', {
cm1: params.size,
cm5: storage.totalUploads,
cm6: storage.numFiles,
cm7: storage.totalDownloads,
cd1: params.type,
cd2: 'cancelled'
});
}
function completedUpload(params) {
return sendEvent(category, 'upload-stopped', {
cm1: params.size,
cm2: params.time,
cm3: params.speed,
cm5: storage.totalUploads,
cm6: storage.numFiles,
cm7: storage.totalDownloads,
cd1: params.type,
cd2: 'completed'
});
}
function startedDownload(params) {
return sendEvent(category, 'download-started', {
cm1: params.size,
cm4: params.ttl,
cm5: storage.totalUploads,
cm6: storage.numFiles,
cm7: storage.totalDownloads
});
}
function stoppedDownload(params) {
return sendEvent(category, 'download-stopped', {
cm1: params.size,
cm5: storage.totalUploads,
cm6: storage.numFiles,
cm7: storage.totalDownloads,
cd2: 'errored',
cd6: params.err
});
}
function cancelledDownload(params) {
setReferrer('cancelled');
return sendEvent(category, 'download-stopped', {
cm1: params.size,
cm5: storage.totalUploads,
cm6: storage.numFiles,
cm7: storage.totalDownloads,
cd2: 'cancelled'
});
}
function stoppedUpload(params) {
return sendEvent(category, 'upload-stopped', {
cm1: params.size,
cm5: storage.totalUploads,
cm6: storage.numFiles,
cm7: storage.totalDownloads,
cd1: params.type,
cd2: 'errored',
cd6: params.err
});
}
function completedDownload(params) {
return sendEvent(category, 'download-stopped', {
cm1: params.size,
cm2: params.time,
cm3: params.speed,
cm5: storage.totalUploads,
cm6: storage.numFiles,
cm7: storage.totalDownloads,
cd2: 'completed'
});
}
function deletedUpload(params) {
return sendEvent(category, 'upload-deleted', {
cm1: params.size,
cm2: params.time,
cm3: params.speed,
cm4: params.ttl,
cm5: storage.totalUploads,
cm6: storage.numFiles,
cm7: storage.totalDownloads,
cd1: params.type,
cd4: params.location
});
}
function unsupported(params) {
return sendEvent(category, 'unsupported', {
cd6: params.err
});
}
function copiedLink(params) {
return sendEvent(category, 'copied', {
cd4: params.location
});
}
function exitEvent(target) {
return sendEvent(category, 'exited', {
cd3: urlToMetric(target.currentTarget.href)
});
}
function addExitHandlers() {
const links = Array.from(document.querySelectorAll('a'));
links.forEach(l => {
if (/^http/.test(l.getAttribute('href'))) {
l.addEventListener('click', exitEvent);
}
});
}
function restartEvent(state) {
setReferrer(state);
return sendEvent(category, 'restarted', {
cd2: state
});
}
function addRestartHandlers() {
const elements = Array.from(document.querySelectorAll('.send-new'));
elements.forEach(el => {
const state = el.getAttribute('data-state');
el.addEventListener('click', restartEvent.bind(null, state));
});
}
export {
copiedLink,
startedUpload,
cancelledUpload,
stoppedUpload,
completedUpload,
deletedUpload,
startedDownload,
cancelledDownload,
stoppedDownload,
completedDownload,
unsupported
};

47
frontend/src/progress.js Normal file
View File

@@ -0,0 +1,47 @@
import { bytes, percent } from './utils';
let percentText = null;
let text = null;
let title = null;
let bar = null;
let updateTitle = false;
const radius = 73;
const circumference = 2 * Math.PI * radius;
document.addEventListener('DOMContentLoaded', function() {
percentText = document.querySelector('.percent-number');
text = document.querySelector('.progress-text');
bar = document.getElementById('bar');
title = document.querySelector('title');
});
document.addEventListener('blur', function() {
updateTitle = true;
});
document.addEventListener('focus', function() {
updateTitle = false;
return title && (title.textContent = 'Firefox Send');
});
function setProgress(params) {
const ratio = params.complete / params.total;
bar.setAttribute('stroke-dashoffset', (1 - ratio) * circumference);
percentText.textContent = Math.floor(ratio * 100);
if (updateTitle) {
title.textContent = percent(ratio);
}
document.l10n
.formatValue('fileSizeProgress', {
partialSize: bytes(params.complete),
totalSize: bytes(params.total)
})
.then(setText);
}
function setText(str) {
text.textContent = str;
}
export { setProgress, setText };

View File

@@ -1,8 +1,38 @@
const { isFile } = require('./utils'); import { isFile } from './utils';
class Storage { class Mem {
constructor(engine) { constructor() {
this.engine = engine; this.items = new Map();
}
get length() {
return this.items.size;
}
getItem(key) {
return this.items.get(key);
}
setItem(key, value) {
return this.items.set(key, value);
}
removeItem(key) {
return this.items.delete(key);
}
key(i) {
return this.items.keys()[i];
}
}
export default class Storage {
constructor() {
try {
this.engine = localStorage || new Mem();
} catch (e) {
this.engine = new Mem();
}
} }
get totalDownloads() { get totalDownloads() {
@@ -56,11 +86,11 @@ class Storage {
} }
getFileById(id) { getFileById(id) {
return this.engine.getItem(id); try {
} return JSON.parse(this.engine.getItem(id));
} catch (e) {
has(property) { return null;
return this.engine.hasOwnProperty(property); }
} }
remove(property) { remove(property) {
@@ -71,5 +101,3 @@ class Storage {
this.engine.setItem(id, JSON.stringify(file)); this.engine.setItem(id, JSON.stringify(file));
} }
} }
module.exports = Storage;

View File

@@ -1,537 +1,250 @@
/* global MAXFILESIZE EXPIRE_SECONDS */ /* global MAXFILESIZE EXPIRE_SECONDS */
require('./common'); import { Raven } from './common';
const FileSender = require('./fileSender'); import FileSender from './fileSender';
const { notify, findMetric, sendEvent, ONE_DAY_IN_MS } = require('./utils'); import {
const bytes = require('bytes'); allowedCopy,
const Storage = require('./storage'); bytes,
const storage = new Storage(localStorage); copyToClipboard,
notify,
gcmCompliant,
ONE_DAY_IN_MS
} from './utils';
import Storage from './storage';
import * as metrics from './metrics';
import * as progress from './progress';
import * as fileList from './fileList';
const $ = require('jquery'); const storage = new Storage();
require('jquery-circle-progress');
const Raven = window.Raven; async function upload(event) {
event.preventDefault();
const pageOne = document.getElementById('page-one');
const link = document.getElementById('link');
const uploadWindow = document.querySelector('.upload-window');
const uploadError = document.getElementById('upload-error');
const uploadProgress = document.getElementById('upload-progress');
const clickOrDrop = event.type === 'drop' ? 'drop' : 'click';
if (storage.has('referrer')) { // don't allow upload if not on upload page
window.referrer = storage.referrer; if (pageOne.hidden) {
storage.remove('referrer'); return;
} else {
window.referrer = 'external';
}
$(document).ready(function() {
$('#page-one').removeAttr('hidden');
$('#file-upload').change(onUpload);
$('.legal-links a, .social-links a, #dl-firefox').click(function(target) {
const metric = findMetric(target.currentTarget.href);
// record exited event by recipient
sendEvent('sender', 'exited', {
cd3: metric
});
});
$('#send-new-completed').click(function() {
// record restarted event
storage.referrer = 'errored-upload';
sendEvent('sender', 'restarted', {
cd2: 'completed'
});
});
$('#send-new-error').click(function() {
// record restarted event
storage.referrer = 'errored-upload';
sendEvent('sender', 'restarted', {
cd2: 'errored'
});
});
$('body').on('dragover', allowDrop).on('drop', onUpload);
// reset copy button
const $copyBtn = $('#copy-btn');
$copyBtn.attr('disabled', false);
$('#link').attr('disabled', false);
$copyBtn.attr('data-l10n-id', 'copyUrlFormButton');
const files = storage.files;
if (files.length === 0) {
toggleHeader();
} else {
// eslint-disable-next-line prefer-const
for (let index in files) {
const id = files[index].fileId;
//check if file still exists before adding to list
checkExistence(id, files[index], true);
}
} }
// copy link to clipboard storage.totalUploads += 1;
$copyBtn.click(() => {
// record copied event from success screen
sendEvent('sender', 'copied', {
cd4: 'success-screen'
});
const aux = document.createElement('input');
aux.setAttribute('value', $('#link').attr('value'));
document.body.appendChild(aux);
aux.select();
document.execCommand('copy');
document.body.removeChild(aux);
//disable button for 3s
$copyBtn.attr('disabled', true);
$('#link').attr('disabled', true);
$copyBtn.html(
'<img src="/resources/check-16.svg" class="icon-check"></img>'
);
window.setTimeout(() => {
$copyBtn.attr('disabled', false);
$('#link').attr('disabled', false);
$copyBtn.attr('data-l10n-id', 'copyUrlFormButton');
}, 3000);
});
$('.upload-window').on('dragover', () => { let file = '';
$('.upload-window').addClass('ondrag'); if (clickOrDrop === 'drop') {
}); if (!event.dataTransfer.files[0]) {
$('.upload-window').on('dragleave', () => { uploadWindow.classList.remove('ondrag');
$('.upload-window').removeClass('ondrag');
});
//initiate progress bar
$('#ul-progress').circleProgress({
value: 0.0,
startAngle: -Math.PI / 2,
fill: '#3B9DFF',
size: 158,
animation: { duration: 300 }
});
//link back to homepage
$('.send-new').attr('href', window.location);
// on file upload by browse or drag & drop
function onUpload(event) {
event.preventDefault();
// don't allow upload if not on upload page
if ($('#page-one').attr('hidden')) {
return; return;
} }
if (
storage.totalUploads += 1; event.dataTransfer.files.length > 1 ||
event.dataTransfer.files[0].size === 0
let file = ''; ) {
if (event.type === 'drop') { uploadWindow.classList.remove('ondrag');
if (!event.originalEvent.dataTransfer.files[0]) { document.l10n.formatValue('uploadPageMultipleFilesAlert').then(str => {
$('.upload-window').removeClass('ondrag'); alert(str);
return;
}
if (
event.originalEvent.dataTransfer.files.length > 1 ||
event.originalEvent.dataTransfer.files[0].size === 0
) {
$('.upload-window').removeClass('ondrag');
document.l10n.formatValue('uploadPageMultipleFilesAlert').then(str => {
alert(str);
});
return;
}
file = event.originalEvent.dataTransfer.files[0];
} else {
file = event.target.files[0];
}
if (file.size > MAXFILESIZE) {
return document.l10n
.formatValue('fileTooBig', { size: bytes(MAXFILESIZE) })
.then(alert);
}
$('#page-one').attr('hidden', true);
$('#upload-error').attr('hidden', true);
$('#upload-progress').removeAttr('hidden');
document.l10n.formatValue('importingFile').then(importingFile => {
$('.progress-text').text(importingFile);
});
//don't allow drag and drop when not on page-one
$('body').off('drop', onUpload);
const fileSender = new FileSender(file);
$('#cancel-upload').click(() => {
fileSender.cancel();
storage.referrer = 'cancelled-upload';
// record upload-stopped (cancelled) by sender
sendEvent('sender', 'upload-stopped', {
cm1: file.size,
cm5: storage.totalUploads,
cm6: unexpiredFiles,
cm7: storage.totalDownloads,
cd1: event.type === 'drop' ? 'drop' : 'click',
cd2: 'cancelled'
}); });
location.reload(); return;
}); }
file = event.dataTransfer.files[0];
fileSender.on('progress', progress => { } else {
const percent = progress[0] / progress[1]; file = event.target.files[0];
// update progress bar
$('#ul-progress').circleProgress('value', percent);
$('#ul-progress').circleProgress().on('circle-animation-end', function() {
$('.percent-number').text(`${Math.floor(percent * 100)}`);
});
$('.progress-text').text(
`${file.name} (${bytes(progress[0], {
decimalPlaces: 1,
fixedDecimals: true
})} of ${bytes(progress[1], { decimalPlaces: 1 })})`
);
});
fileSender.on('hashing', isStillHashing => {
// The file is being hashed
if (isStillHashing) {
document.l10n.formatValue('verifyingFile').then(verifyingFile => {
$('.progress-text').text(verifyingFile);
});
}
});
let uploadStart;
fileSender.on('encrypting', isStillEncrypting => {
// The file is being encrypted
if (isStillEncrypting) {
document.l10n.formatValue('encryptingFile').then(encryptingFile => {
$('.progress-text').text(encryptingFile);
});
} else {
uploadStart = Date.now();
}
});
let t;
const startTime = Date.now();
const unexpiredFiles = storage.numFiles + 1;
// record upload-started event by sender
sendEvent('sender', 'upload-started', {
cm1: file.size,
cm5: storage.totalUploads,
cm6: unexpiredFiles,
cm7: storage.totalDownloads,
cd1: event.type === 'drop' ? 'drop' : 'click',
cd5: window.referrer
});
// For large files we need to give the ui a tick to breathe and update
// before we kick off the FileSender
setTimeout(() => {
fileSender
.upload()
.then(info => {
const endTime = Date.now();
const totalTime = endTime - startTime;
const uploadTime = endTime - uploadStart;
const uploadSpeed = file.size / (uploadTime / 1000);
const expiration = EXPIRE_SECONDS * 1000;
// record upload-stopped (completed) by sender
sendEvent('sender', 'upload-stopped', {
cm1: file.size,
cm2: totalTime,
cm3: uploadSpeed,
cm5: storage.totalUploads,
cm6: unexpiredFiles,
cm7: storage.totalDownloads,
cd1: event.type === 'drop' ? 'drop' : 'click',
cd2: 'completed'
});
const fileData = {
name: file.name,
size: file.size,
fileId: info.fileId,
url: info.url,
secretKey: info.secretKey,
deleteToken: info.deleteToken,
creationDate: new Date(),
expiry: expiration,
totalTime: totalTime,
typeOfUpload: event.type === 'drop' ? 'drop' : 'click',
uploadSpeed: uploadSpeed
};
storage.addFile(info.fileId, fileData);
$('#upload-filename').attr(
'data-l10n-id',
'uploadSuccessConfirmHeader'
);
t = window.setTimeout(() => {
$('#page-one').attr('hidden', true);
$('#upload-progress').attr('hidden', true);
$('#upload-error').attr('hidden', true);
$('#share-link').removeAttr('hidden');
}, 1000);
populateFileList(fileData);
document.l10n.formatValue('notifyUploadDone').then(str => {
notify(str);
});
})
.catch(err => {
// err is 0 when coming from a cancel upload event
if (err === 0) {
return;
}
// only show error page when the error is anything other than user cancelling the upload
Raven.captureException(err);
$('#page-one').attr('hidden', true);
$('#upload-progress').attr('hidden', true);
$('#upload-error').removeAttr('hidden');
window.clearTimeout(t);
// record upload-stopped (errored) by sender
sendEvent('sender', 'upload-stopped', {
cm1: file.size,
cm5: storage.totalUploads,
cm6: unexpiredFiles,
cm7: storage.totalDownloads,
cd1: event.type === 'drop' ? 'drop' : 'click',
cd2: 'errored',
cd6: err
});
});
}, 10);
} }
function allowDrop(ev) { if (file.size > MAXFILESIZE) {
ev.preventDefault(); return document.l10n
.formatValue('fileTooBig', { size: bytes(MAXFILESIZE) })
.then(alert);
} }
function checkExistence(id, file, populate) { pageOne.hidden = true;
const xhr = new XMLHttpRequest(); uploadError.hidden = true;
xhr.onreadystatechange = () => { uploadProgress.hidden = false;
if (xhr.readyState === XMLHttpRequest.DONE) { document.l10n
if (xhr.status === 200) { .formatValue('uploadingPageProgress', {
if (populate) { size: bytes(file.size),
populateFileList(file); filename: file.name
} })
} else if (xhr.status === 404) { .then(str => {
storage.remove(id); document.getElementById('upload-filename').textContent = str;
if (storage.numFiles === 0) { });
toggleHeader(); document.l10n.formatValue('importingFile').then(progress.setText);
} //don't allow drag and drop when not on page-one
document.body.removeEventListener('drop', upload);
const fileSender = new FileSender(file);
document.getElementById('cancel-upload').addEventListener('click', () => {
fileSender.cancel();
metrics.cancelledUpload({
size: file.size,
type: clickOrDrop
});
location.reload();
});
let uploadStart;
fileSender.on('progress', data => {
uploadStart = uploadStart || Date.now();
progress.setProgress({
complete: data[0],
total: data[1]
});
});
fileSender.on('encrypting', () => {
document.l10n.formatValue('encryptingFile').then(progress.setText);
});
let t;
const startTime = Date.now();
metrics.startedUpload({
size: file.size,
type: clickOrDrop
});
// For large files we need to give the ui a tick to breathe and update
// before we kick off the FileSender
setTimeout(() => {
fileSender
.upload()
.then(info => {
const endTime = Date.now();
const time = endTime - startTime;
const uploadTime = endTime - uploadStart;
const speed = file.size / (uploadTime / 1000);
const expiration = EXPIRE_SECONDS * 1000;
link.setAttribute('value', `${info.url}#${info.secretKey}`);
metrics.completedUpload({
size: file.size,
time,
speed,
type: clickOrDrop
});
const fileData = {
name: file.name,
size: file.size,
fileId: info.fileId,
url: info.url,
secretKey: info.secretKey,
deleteToken: info.deleteToken,
creationDate: new Date(),
expiry: expiration,
totalTime: time,
typeOfUpload: clickOrDrop,
uploadSpeed: speed
};
document.getElementById('delete-file').addEventListener('click', () => {
FileSender.delete(fileData.fileId, fileData.deleteToken).then(() => {
const ttl =
ONE_DAY_IN_MS - (Date.now() - fileData.creationDate.getTime());
metrics
.deletedUpload({
size: fileData.size,
time: fileData.totalTime,
speed: fileData.uploadSpeed,
type: fileData.typeOfUpload,
location: 'success-screen',
ttl
})
.then(() => {
storage.remove(fileData.fileId);
location.reload();
});
});
});
storage.addFile(info.fileId, fileData);
pageOne.hidden = true;
uploadProgress.hidden = true;
uploadError.hidden = true;
document.getElementById('share-link').hidden = false;
fileList.addFile(fileData);
document.l10n.formatValue('notifyUploadDone').then(str => {
notify(str);
});
})
.catch(err => {
// err is 0 when coming from a cancel upload event
if (err === 0) {
return;
} }
} // only show error page when the error is anything other than user cancelling the upload
}; Raven.captureException(err);
xhr.open('get', '/exists/' + id, true); pageOne.hidden = true;
xhr.send(); uploadProgress.hidden = true;
} uploadError.hidden = false;
//update file table with current files in storage
function populateFileList(file) {
const row = document.createElement('tr');
const name = document.createElement('td');
const link = document.createElement('td');
const $copyIcon = $('<img>', {
src: '/resources/copy-16.svg',
class: 'icon-copy',
'data-l10n-id': 'copyUrlHover'
});
const expiry = document.createElement('td');
const del = document.createElement('td');
const $delIcon = $('<img>', {
src: '/resources/close-16.svg',
class: 'icon-delete',
'data-l10n-id': 'deleteButtonHover'
});
const popupDiv = document.createElement('div');
const $popupText = $('<div>', { class: 'popuptext' });
const cellText = document.createTextNode(file.name);
const url = file.url.trim() + `#${file.secretKey}`.trim();
$('#link').attr('value', url);
$('#copy-text').attr('data-l10n-args', '{"filename": "' + file.name + '"}');
$('#copy-text').attr('data-l10n-id', 'copyUrlFormLabelWithName');
$popupText.attr('tabindex', '-1');
name.appendChild(cellText);
// create delete button
const delSpan = document.createElement('span');
$(delSpan).addClass('icon-cancel-1');
$(delSpan).attr('data-l10n-id', 'deleteButtonHover');
del.appendChild(delSpan);
const linkSpan = document.createElement('span');
$(linkSpan).addClass('icon-docs');
$(linkSpan).attr('data-l10n-id', 'copyUrlHover');
link.appendChild(linkSpan);
link.style.color = '#0A8DFF';
//copy link to clipboard when icon clicked
$copyIcon.click(function() {
// record copied event from upload list
sendEvent('sender', 'copied', {
cd4: 'upload-list'
});
const aux = document.createElement('input');
aux.setAttribute('value', url);
document.body.appendChild(aux);
aux.select();
document.execCommand('copy');
document.body.removeChild(aux);
document.l10n.formatValue('copiedUrl').then(translated => {
link.innerHTML = translated;
});
window.setTimeout(() => {
const linkImg = document.createElement('img');
$(linkImg).addClass('icon-copy');
$(linkImg).attr('data-l10n-id', 'copyUrlHover');
$(linkImg).attr('src', '/resources/copy-16.svg');
$(link).html(linkImg);
}, 500);
});
file.creationDate = new Date(file.creationDate);
const future = new Date();
future.setTime(file.creationDate.getTime() + file.expiry);
let countdown = 0;
countdown = future.getTime() - Date.now();
let minutes = Math.floor(countdown / 1000 / 60);
let hours = Math.floor(minutes / 60);
let seconds = Math.floor(countdown / 1000 % 60);
poll();
function poll() {
countdown = future.getTime() - Date.now();
minutes = Math.floor(countdown / 1000 / 60);
hours = Math.floor(minutes / 60);
seconds = Math.floor(countdown / 1000 % 60);
let t;
if (hours >= 1) {
expiry.innerHTML = hours + 'h ' + minutes % 60 + 'm';
t = window.setTimeout(() => {
poll();
}, 60000);
} else if (hours === 0) {
expiry.innerHTML = minutes + 'm ' + seconds + 's';
t = window.setTimeout(() => {
poll();
}, 1000);
}
//remove from list when expired
if (countdown <= 0) {
storage.remove(file.fileId);
$(expiry).parents('tr').remove();
window.clearTimeout(t); window.clearTimeout(t);
toggleHeader();
metrics.stoppedUpload({
size: file.size,
type: clickOrDrop,
err
});
});
}, 10);
}
document.addEventListener('DOMContentLoaded', function() {
gcmCompliant()
.then(function() {
const pageOne = document.getElementById('page-one');
const copyBtn = document.getElementById('copy-btn');
const link = document.getElementById('link');
const uploadWindow = document.querySelector('.upload-window');
pageOne.hidden = false;
document.getElementById('file-upload').addEventListener('change', upload);
document.body.addEventListener('dragover', allowDrop);
document.body.addEventListener('drop', upload);
// reset copy button
copyBtn.disabled = !allowedCopy();
copyBtn.setAttribute('data-l10n-id', 'copyUrlFormButton');
link.disabled = false;
// copy link to clipboard
copyBtn.addEventListener('click', () => {
if (allowedCopy() && copyToClipboard(link.getAttribute('value'))) {
metrics.copiedLink({ location: 'success-screen' });
//disable button for 3s
copyBtn.disabled = true;
link.disabled = true;
copyBtn.innerHtml =
'<img src="/resources/check-16.svg" class="icon-check"></img>';
setTimeout(() => {
copyBtn.disabled = !allowedCopy();
copyBtn.setAttribute('data-l10n-id', 'copyUrlFormButton');
link.disabled = false;
}, 3000);
}
});
uploadWindow.addEventListener('dragover', () =>
uploadWindow.classList.add('ondrag')
);
uploadWindow.addEventListener('dragleave', () =>
uploadWindow.classList.remove('ondrag')
);
// on file upload by browse or drag & drop
function allowDrop(ev) {
ev.preventDefault();
} }
} })
.catch(err => {
// create popup metrics.unsupported({ err }).then(() => {
popupDiv.classList.add('popup'); location.replace('/unsupported/gcm');
const $popupMessage = $('<div>', { class: 'popup-message' });
$popupMessage.attr('data-l10n-id', 'deletePopupText');
const $popupAction = $('<div>', { class: 'popup-action' });
const $popupNvmSpan = $('<span>', { class: 'popup-no' });
$popupNvmSpan.attr('data-l10n-id', 'deletePopupCancel');
const $popupDelSpan = $('<span>', { class: 'popup-yes' });
$popupDelSpan.attr('data-l10n-id', 'deletePopupYes');
$popupText.html([$popupMessage, $popupAction]);
$popupAction.html([$popupNvmSpan, $popupDelSpan]);
// add data cells to table row
row.appendChild(name);
$(link).append($copyIcon);
row.appendChild(link);
row.appendChild(expiry);
$(popupDiv).append($popupText);
$(del).append($delIcon);
del.appendChild(popupDiv);
row.appendChild(del);
$('tbody').append(row); //add row to table
const unexpiredFiles = storage.numFiles;
// delete file
$popupText.find('.popup-yes').click(e => {
FileSender.delete(file.fileId, file.deleteToken).then(() => {
$(e.target).parents('tr').remove();
const timeToExpiry =
ONE_DAY_IN_MS - (Date.now() - file.creationDate.getTime());
// record upload-deleted from file list
sendEvent('sender', 'upload-deleted', {
cm1: file.size,
cm2: file.totalTime,
cm3: file.uploadSpeed,
cm4: timeToExpiry,
cm5: storage.totalUploads,
cm6: unexpiredFiles,
cm7: storage.totalDownloads,
cd1: file.typeOfUpload,
cd4: 'upload-list'
}).then(() => {
storage.remove(file.fileId);
});
toggleHeader();
}); });
}); });
document.getElementById('delete-file').onclick = () => {
FileSender.delete(file.fileId, file.deleteToken).then(() => {
const timeToExpiry =
ONE_DAY_IN_MS - (Date.now() - file.creationDate.getTime());
// record upload-deleted from success screen
sendEvent('sender', 'upload-deleted', {
cm1: file.size,
cm2: file.totalTime,
cm3: file.uploadSpeed,
cm4: timeToExpiry,
cm5: storage.totalUploads,
cm6: unexpiredFiles,
cm7: storage.totalDownloads,
cd1: file.typeOfUpload,
cd4: 'success-screen'
}).then(() => {
storage.remove(file.fileId);
location.reload();
});
});
};
// show popup
$delIcon.click(function() {
$popupText.addClass('show');
$popupText.focus();
});
// hide popup
$popupText.find('.popup-no').click(function(e) {
e.stopPropagation();
$popupText.removeClass('show');
});
$popupText.click(function(e) {
e.stopPropagation();
});
//close when popup loses focus
$popupText.blur(() => {
$popupText.removeClass('show');
});
toggleHeader();
}
function toggleHeader() {
//hide table header if empty list
if (document.querySelector('tbody').childNodes.length === 1) {
$('#file-list').attr('hidden', true);
} else {
$('#file-list').removeAttr('hidden');
}
}
}); });

View File

@@ -60,41 +60,22 @@ function gcmCompliant() {
) )
.then(() => { .then(() => {
return Promise.resolve(); return Promise.resolve();
})
.catch(err => {
return Promise.reject();
}); });
}) })
.catch(err => { .catch(err => {
return Promise.reject(); return loadShim();
}); });
} catch (err) { } catch (err) {
return Promise.reject(); return loadShim();
} }
} function loadShim() {
return new Promise((resolve, reject) => {
function findMetric(href) { const shim = document.createElement('script');
switch (href) { shim.src = '/cryptofill.js';
case 'https://www.mozilla.org/': shim.addEventListener('load', resolve);
return 'mozilla'; shim.addEventListener('error', reject);
case 'https://www.mozilla.org/about/legal': document.head.appendChild(shim);
return 'legal'; });
case 'https://testpilot.firefox.com/about':
return 'about';
case 'https://testpilot.firefox.com/privacy':
return 'privacy';
case 'https://testpilot.firefox.com/terms':
return 'terms';
case 'https://www.mozilla.org/privacy/websites/#cookies':
return 'cookies';
case 'https://github.com/mozilla/send':
return 'github';
case 'https://twitter.com/FxTestPilot':
return 'twitter';
case 'https://www.mozilla.org/firefox/new/?scene=2':
return 'download-firefox';
default:
return 'other';
} }
} }
@@ -102,21 +83,68 @@ function isFile(id) {
return /^[0-9a-fA-F]{10}$/.test(id); return /^[0-9a-fA-F]{10}$/.test(id);
} }
function sendEvent() { function copyToClipboard(str) {
return window.analytics.sendEvent const aux = document.createElement('input');
.apply(window.analytics, arguments) aux.setAttribute('value', str);
.catch(() => 0); aux.contentEditable = true;
aux.readOnly = true;
document.body.appendChild(aux);
if (navigator.userAgent.match(/iphone|ipad|ipod/i)) {
const range = document.createRange();
range.selectNodeContents(aux);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
aux.setSelectionRange(0, str.length);
} else {
aux.select();
}
const result = document.execCommand('copy');
document.body.removeChild(aux);
return result;
}
const LOCALIZE_NUMBERS = !!(
typeof Intl === 'object' &&
Intl &&
typeof Intl.NumberFormat === 'function'
);
const UNITS = ['B', 'kB', 'MB', 'GB'];
function bytes(num) {
const exponent = Math.min(Math.floor(Math.log10(num) / 3), UNITS.length - 1);
const n = Number(num / Math.pow(1000, exponent));
const nStr = LOCALIZE_NUMBERS
? n.toLocaleString(navigator.languages, {
minimumFractionDigits: 1,
maximumFractionDigits: 1
})
: n.toFixed(1);
return `${nStr}${UNITS[exponent]}`;
}
function percent(ratio) {
return LOCALIZE_NUMBERS
? ratio.toLocaleString(navigator.languages, { style: 'percent' })
: `${Math.floor(ratio * 100)}%`;
}
function allowedCopy() {
const support = !!document.queryCommandSupported;
return support ? document.queryCommandSupported('copy') : false;
} }
const ONE_DAY_IN_MS = 86400000; const ONE_DAY_IN_MS = 86400000;
module.exports = { export {
allowedCopy,
bytes,
percent,
copyToClipboard,
arrayToHex, arrayToHex,
hexToArray, hexToArray,
notify, notify,
gcmCompliant, gcmCompliant,
findMetric,
isFile, isFile,
sendEvent,
ONE_DAY_IN_MS ONE_DAY_IN_MS
}; };

6724
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,11 @@
{ {
"name": "firefox-send", "name": "firefox-send",
"description": "File Sharing Experiment", "description": "File Sharing Experiment",
"version": "1.0.4", "version": "1.1.1",
"author": "Mozilla (https://mozilla.org)", "author": "Mozilla (https://mozilla.org)",
"dependencies": { "dependencies": {
"aws-sdk": "^2.89.0", "aws-sdk": "^2.98.0",
"body-parser": "^1.17.2", "body-parser": "^1.17.2",
"bytes": "^2.5.0",
"connect-busboy": "0.0.2", "connect-busboy": "0.0.2",
"convict": "^3.0.0", "convict": "^3.0.0",
"express": "^4.15.3", "express": "^4.15.3",
@@ -14,46 +13,73 @@
"helmet": "^3.8.0", "helmet": "^3.8.0",
"mozlog": "^2.1.1", "mozlog": "^2.1.1",
"raven": "^2.1.0", "raven": "^2.1.0",
"redis": "^2.7.1" "redis": "^2.8.0"
}, },
"devDependencies": { "devDependencies": {
"asmcrypto.js": "0.0.11",
"autoprefixer": "^7.1.2",
"babel-core": "^6.25.0",
"babel-loader": "^7.1.1",
"babel-polyfill": "^6.23.0", "babel-polyfill": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
"bel": "^5.0.3",
"browserify": "^14.4.0", "browserify": "^14.4.0",
"copy-webpack-plugin": "^4.0.1",
"cross-env": "^5.0.5",
"css-loader": "^0.28.4",
"css-mqpacker": "^6.0.1",
"cssnano": "^3.10.0",
"eslint": "^4.3.0", "eslint": "^4.3.0",
"eslint-plugin-mocha": "^4.11.0", "eslint-plugin-mocha": "^4.11.0",
"eslint-plugin-node": "^5.1.1", "eslint-plugin-node": "^5.1.1",
"eslint-plugin-security": "^1.4.0", "eslint-plugin-security": "^1.4.0",
"extract-loader": "^1.0.0",
"file-loader": "^0.11.2",
"git-rev-sync": "^1.9.1", "git-rev-sync": "^1.9.1",
"jquery": "^3.2.1", "html-loader": "^0.5.1",
"jquery-circle-progress": "^1.2.2", "html-webpack-plugin": "^2.30.1",
"husky": "^0.14.3",
"l20n": "^5.0.0", "l20n": "^5.0.0",
"lint-staged": "^4.0.3",
"mkdirp": "^0.5.1",
"mocha": "^3.4.2", "mocha": "^3.4.2",
"npm-run-all": "^4.0.2", "npm-run-all": "^4.0.2",
"postcss-cli": "^4.1.0",
"postcss-loader": "^2.0.6",
"prettier": "^1.5.3", "prettier": "^1.5.3",
"proxyquire": "^1.8.0", "proxyquire": "^1.8.0",
"raven-js": "^3.17.0", "raven-js": "^3.17.0",
"rimraf": "^2.6.1",
"selenium-webdriver": "^3.5.0", "selenium-webdriver": "^3.5.0",
"sinon": "^2.3.8", "sinon": "^2.3.8",
"stylelint": "^8.0.0", "stylelint": "^8.0.0",
"stylelint-config-standard": "^17.0.0", "stylelint-config-standard": "^17.0.0",
"stylelint-no-unsupported-browser-features": "^1.0.0",
"supertest": "^3.0.0", "supertest": "^3.0.0",
"testpilot-ga": "^0.3.0", "testpilot-ga": "^0.3.0",
"uglifyify": "^4.0.3" "webcrypto-liner": "^0.1.25",
"webpack": "^3.5.4",
"webpack-dev-middleware": "^1.12.0"
}, },
"engines": { "engines": {
"node": ">=8.0.0" "node": ">=8.2.0"
}, },
"homepage": "https://github.com/mozilla/send/", "homepage": "https://github.com/mozilla/send/",
"license": "MPL-2.0", "license": "MPL-2.0",
"repository": "mozilla/send", "repository": "mozilla/send",
"availableLanguages": [ "availableLanguages": [
"ast",
"az", "az",
"ca", "ca",
"cs", "cs",
"cy", "cy",
"de", "de",
"dsb", "dsb",
"el",
"en-US", "en-US",
"es-AR",
"es-CL",
"es-ES", "es-ES",
"es-MX", "es-MX",
"fr", "fr",
@@ -64,6 +90,7 @@
"it", "it",
"ja", "ja",
"kab", "kab",
"ko",
"ms", "ms",
"nb-NO", "nb-NO",
"nl", "nl",
@@ -75,29 +102,45 @@
"sl", "sl",
"sr", "sr",
"sv-SE", "sv-SE",
"tr",
"uk",
"vi",
"zh-CN", "zh-CN",
"zh-TW" "zh-TW"
], ],
"scripts": { "scripts": {
"precommit": "lint-staged",
"clean": "rimraf dist",
"build": "npm-run-all build:*", "build": "npm-run-all build:*",
"build:upload": "browserify frontend/src/upload.js -g uglifyify -o public/upload.js", "build:js": "webpack -p",
"build:download": "browserify frontend/src/download.js -g uglifyify -o public/download.js",
"build:version": "node scripts/version", "build:version": "node scripts/version",
"build:vendor": "cp node_modules/l20n/dist/web/l20n.min.js node_modules/babel-polyfill/dist/polyfill.min.js public", "contributors": "git shortlog -s | awk -F\\t '{print $2}' > CONTRIBUTORS",
"dev": "npm run build && npm start", "dev": "npm run clean && npm run build && npm start",
"format": "prettier '{frontend/src/,scripts/,server/,test/**/!(bundle)}*.js' 'public/*.css' --single-quote --write", "format": "prettier '{,frontend/src/,scripts/,server/,test/**/!(bundle)}*.{js,css}' --single-quote --write",
"get-prod-locales": "node scripts/get-prod-locales", "get-prod-locales": "node scripts/get-prod-locales",
"get-prod-locales:write": "npm run get-prod-locales -- --write", "get-prod-locales:write": "npm run get-prod-locales -- --write",
"lint": "npm-run-all lint:*", "lint": "npm-run-all lint:*",
"lint:css": "stylelint 'public/*.css'", "lint:css": "stylelint 'frontend/src/*.css'",
"lint:js": "eslint .", "lint:js": "eslint .",
"lint-locales": "node scripts/lint-locales", "lint-locales": "node scripts/lint-locales",
"lint-locales:dev": "npm run lint-locales", "lint-locales:dev": "npm run lint-locales",
"lint-locales:prod": "npm run lint-locales -- --production", "lint-locales:prod": "npm run lint-locales -- --production",
"start": "node server/server", "start": "node server/server",
"test": "npm-run-all test:*", "test": "cross-env NODE_ENV=test npm-run-all test:*",
"test:unit": "mocha test/unit", "test:unit": "mocha test/unit",
"test:server": "mocha test/server", "test:server": "mocha test/server",
"test--browser": "browserify test/frontend/frontend.bundle.js -o test/frontend/bundle.js -d && node test/frontend/driver.js" "test--browser": "browserify test/frontend/frontend.bundle.js -o test/frontend/bundle.js -d && node test/frontend/driver.js"
},
"lint-staged": {
"*.js": [
"prettier --single-quote --write",
"eslint",
"git add"
],
"*.css": [
"prettier --single-quote --write",
"stylelint",
"git add"
]
} }
} }

15
postcss.config.js Normal file
View File

@@ -0,0 +1,15 @@
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');
const mqpacker = require('css-mqpacker');
const conf = require('./server/config');
const options = {
plugins: [autoprefixer, mqpacker, cssnano]
};
if (conf.env === 'development') {
options.map = { inline: true };
}
module.exports = options;

22
public/cryptofill.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,99 @@
// Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = esperimentu web
siteFeedback = Feedback
uploadPageHeader = Compartición privada y cifrada de ficheros
uploadPageExplainer = Unvia ficheros pente un enllaz seguru, priváu y cifráu que caduca automáticamente p'asegurar que les tos coses nun queden siempres na rede.
uploadPageLearnMore = Deprendi más
uploadPageDropMessage = Suelta equí'l to ficheru p'aniciar la xuba
uploadPageSizeMessage = Pal meyor funcionamientu, lo meyor ye que'l to ficheru seya menor de 1GB
uploadPageBrowseButton = Esbilla un ficheru nel to ordenador
.title = Esbilla un ficheru nel to ordenador
uploadPageBrowseButton1 = Esbilla un ficheru pa unviar
.title = Esbilla un ficheru pa unviar
uploadPageMultipleFilesAlert = Anguaño nun se sofita la xuba múltiple de ficheros o carpetes.
uploadPageBrowseButtonTitle = Xubir ficheru
uploadingPageProgress = Xubiendo { $filename } ({ $size })
importingFile = Importando...
verifyingFile = Verificando...
encryptingFile = Cifrando...
decryptingFile = Descifrando...
notifyUploadDone = Finó la to xuba.
uploadingPageMessage = Namái que'l ficheru xuba, sedrás a afitar les opciones de caducidá.
uploadingPageCancel = Encaboxar xuba
.title = Encaboxar xuba
uploadCancelNotification = Encaboxóse la to xuba.
uploadingPageLargeFileMessage = Esti ficheru ye grande y pue entardar daqué en xubir. ¡Paciencia!
uploadingFileNotification = Avísame cuando se complete la xuba.
uploadSuccessConfirmHeader = Preparáu pa unviar
uploadSvgAlt
.alt = Xubir
uploadSuccessTimingHeader = L'enllaz del to ficheru caducará dempués d'una descarga o en 24 hores.
copyUrlFormLabelWithName = Copia y comparti l'enllaz pa unviar el to ficheru: { $filename }
// Note: Title text for button should be the same.
copyUrlFormButton = Copiar al cartafueyu
.title = Copiar al cartafueyu
copiedUrl = ¡Copióse!
// Note: Title text for button should be the same.
deleteFileButton = Desaniciar ficheru
.title = Desaniciar ficheru
// Note: Title text for button should be the same.
sendAnotherFileLink = Unviar otru ficheru
.title = Unviar otru ficheru
// Alternative text used on the download link/button (indicates an action).
downloadAltText
.alt = Baxar
downloadFileName = Baxar { $filename }
downloadFileSize = ({ $size })
// Firefox Send is a brand name and should not be localized.
downloadMessage = El to collaciu unvióte un ficheru usando Firefox Send, un serviciu que te permite compartir ficheros con un enllaz seguru, priváu y cifráu que caduca automáticamente p'asegurar que les to coses nun queden siempres na rede.
// Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Baxar
.title = Baxar
downloadNotification = Completóse la to descarga.
downloadFinish = Descarga completada
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } de { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Prueba Firefox Send
.title = Prueba Firefox Send
downloadingPageProgress = Baxando { $filename } ({ $size })
downloadingPageMessage = Dexa esta llingüeta abierta entrín vamos en cata del to ficheru y lu desciframos, por favor.
errorAltText
.alt = Fallu de xuba
errorPageHeader = ¡Daqué foi mal!
errorPageMessage = Hebo un fallu xubiendo'l ficheru.
errorPageLink = Unviar otru ficheru
fileTooBig = Esti ficheru ye mui grande como pa xubilu. Debería tener menos de { $size }.
linkExpiredAlt
.alt = Enllaz caducáu
expiredPageHeader = ¡Esti enllaz caducó o enxamás nun esistó!
notSupportedHeader = El to restolador nun ta sofitáu.
// Firefox Send is a brand name and should not be localized.
notSupportedDetail = Desafortunadamente esti restolador nun sofita la teunoloxía web qu'usa Firefox Send. Precisarás d'usar otru restolador. ¡Aconseyámoste Firefox!
notSupportedLink = ¿Por qué'l mio restolador nun ta sofitáu?
notSupportedOutdatedDetail = Desafortunadamente esta versión de Firefox nun sofita la teunoloxía web qu'usa Firefox Send. Precisarás d'anovar Firefox.
updateFirefox = Anovar Firefox
downloadFirefoxButtonSub = Descarga de baldre
uploadedFile = Ficheru
copyFileList = Copiar URL
// expiryFileList is used as a column header
expiryFileList = Caduca en
deleteFileList = Desaniciar
nevermindButton = Nun m'importa
legalHeader = Términos y privacidá
legalNoticeTestPilot = Anguaño Firefox Send ye un esperimentu de Test Pilot y ta suxetu a los <a>Términos de serviciu</a> y l'<a>Avisu de privacidá</a> de Test Pilot. <a>Equí</a> pues deprender más tocante a esti esperimentu y la so recoyida de datos.
legalNoticeMozilla = L'usu de Firefox Send tamién ta suxetu al <a>Avisu de privacidá</a> y a los <a>Términos d'usu de la páxina web</a> de Mozilla.
deletePopupText = ¿Desaniciar esti ficheru?
deletePopupYes = Sí
deletePopupCancel = Encaboxar
deleteButtonHover
.title = Desaniciar
copyUrlHover
.title = Copiar URL
footerLinkLegal = Llegal
// Test Pilot is a proper name and should not be localized.
footerLinkAbout = Tocante a Test Pilot
footerLinkPrivacy = Privacidá
footerLinkTerms = Términos
footerLinkCookies = Cookies

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Yükləmək üçün faylınızı buraya daşıyın
uploadPageSizeMessage = Xidmətin daha yaxşı işləməsi üçün faylınız 1 GB-dan az olmalıdır uploadPageSizeMessage = Xidmətin daha yaxşı işləməsi üçün faylınız 1 GB-dan az olmalıdır
uploadPageBrowseButton = Kompüterinizdən fayl seçin uploadPageBrowseButton = Kompüterinizdən fayl seçin
.title = Kompüterinizdən fayl seçin .title = Kompüterinizdən fayl seçin
uploadPageBrowseButton1 = Yüklənəcək faylı seçin
.title = Yüklənəcək faylı seçin
uploadPageMultipleFilesAlert = Birdən çox fayl və ya qovluq yükləmə hələlik dəstəklənmir. uploadPageMultipleFilesAlert = Birdən çox fayl və ya qovluq yükləmə hələlik dəstəklənmir.
uploadPageBrowseButtonTitle = Fayl yüklə uploadPageBrowseButtonTitle = Fayl yüklə
uploadingPageHeader = Faylınız yüklənir uploadingPageProgress = { $filename } ({ $size }) yüklənir
importingFile = İdxal edilir… importingFile = İdxal edilir…
verifyingFile = Təsdiqlənir… verifyingFile = Təsdiqlənir…
encryptingFile = Şifrələnir... encryptingFile = Şifrələnir...
@@ -50,6 +52,8 @@ downloadButtonLabel = Endir
.title = Endir .title = Endir
downloadNotification = Endirməniz tamamlandı. downloadNotification = Endirməniz tamamlandı.
downloadFinish = Endirmə Tamamlandı downloadFinish = Endirmə Tamamlandı
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } / { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Firefox Send Yoxla sendYourFilesLink = Firefox Send Yoxla
.title = Firefox Send Yoxla .title = Firefox Send Yoxla
@@ -67,6 +71,7 @@ expiredPageHeader = Keçidin vaxtı çıxıb və ya heç vaxt olmayıb!
notSupportedHeader = Səyyahınız dəstəklənmir. notSupportedHeader = Səyyahınız dəstəklənmir.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Heyf ki, bu səyyah Firefox Send-ə güc verən web texnologiyalarını dəstəkləmir. Fərqli bir səyyah yoxlamalısınız. Biz Firefox məsləhət görürük! notSupportedDetail = Heyf ki, bu səyyah Firefox Send-ə güc verən web texnologiyalarını dəstəkləmir. Fərqli bir səyyah yoxlamalısınız. Biz Firefox məsləhət görürük!
notSupportedLink = Səyyahım niyə dəstəklənmir?
notSupportedOutdatedDetail = Heyf ki, Firefox səyyahının bu versiyası Firefox Send-ə güc verən web texnologiyalarını dəstəkləmir. Səyyahınızı yeniləməlisiniz. notSupportedOutdatedDetail = Heyf ki, Firefox səyyahının bu versiyası Firefox Send-ə güc verən web texnologiyalarını dəstəkləmir. Səyyahınızı yeniləməlisiniz.
updateFirefox = Firefox-u Yenilə updateFirefox = Firefox-u Yenilə
downloadFirefoxButtonSub = Pulsuz Endir downloadFirefoxButtonSub = Pulsuz Endir

View File

@@ -0,0 +1,65 @@
// Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = ওয়েব গবেষণা
siteFeedback = প্রতিক্রিয়া
uploadPageLearnMore = আরও জানুন
uploadPageBrowseButton = আপনার কম্পিউটারে ফাইল নির্বাচন করুন
.title = আপনার কম্পিউটারে ফাইল নির্বাচন করুন
uploadPageBrowseButtonTitle = ফাইল আপলোড
importingFile = ইম্পোর্ট হচ্ছে...
verifyingFile = যাচাই হচ্ছে...
encryptingFile = ইনক্রিপট হচ্ছে...
decryptingFile = ডিক্রিপট হচ্ছে...
notifyUploadDone = আপনার আপলোড সম্পন্ন হয়েছে।
uploadingPageCancel = আপলোড বাতিল করুন
.title = আপলোড বাতিল করুন
uploadCancelNotification = আপনার অাপলোড বাতিল করা হয়েছে।
uploadSuccessConfirmHeader = পাঠানোর জন্য প্রস্তুত
uploadSvgAlt
.alt = আপলোড
// Note: Title text for button should be the same.
copyUrlFormButton = ক্লিপবোর্ডে কপি করুন
.title = ক্লিপবোর্ডে কপি করুন
copiedUrl = কপি করা হয়েছে!
// Note: Title text for button should be the same.
deleteFileButton = ফাইল মুছুন
.title = ফাইল মুছুন
// Note: Title text for button should be the same.
sendAnotherFileLink = আরেকটি ফাইল পাঠান
.title = আরেকটি ফাইল পাঠান
// Alternative text used on the download link/button (indicates an action).
downloadAltText
.alt = ডাউনলোড
downloadFileName = ডাউনলোড { $filename }
downloadFileSize = ({ $size })
// Text and title used on the download link/button (indicates an action).
downloadButtonLabel = ডাউনলোড
.title = ডাউনলোড
downloadNotification = আপনার ডাউনলোড সম্পন্ন হয়েছে।
downloadFinish = ডাউনলোড সম্পন্ন
errorAltText
.alt = আপালোডে ত্রুটি
errorPageHeader = কোন সমস্যা হয়েছে!
errorPageLink = আরেকটি ফাইল পাঠান
updateFirefox = Firefox হালনাগাদ করুন
downloadFirefoxButtonSub = বিনামূল্যে ডাউনলোড
uploadedFile = ফাইল
copyFileList = URL অনুলিপি করুন
// expiryFileList is used as a column header
expiryFileList = মেয়াদোত্তীর্ণ তারিখ
deleteFileList = মুছে ফেলুন
nevermindButton = কিছু মনে করবেন না
legalHeader = শর্তাবলী এবং গোপনীয়তা
deletePopupText = ফাইলটি মুছতে চান?
deletePopupYes = হ্যাঁ
deletePopupCancel = বাতিল
deleteButtonHover
.title = মুছে ফেলুন
copyUrlHover
.title = URL অনুলিপি করুন
footerLinkLegal = আইনগত
// Test Pilot is a proper name and should not be localized.
footerLinkAbout = Test Pilot পরিচিতি
footerLinkPrivacy = গোপনীয়তা
footerLinkTerms = শর্তাবলী
footerLinkCookies = কুকি

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Arrossegueu el fitxer aquí per començar a pujar-lo
uploadPageSizeMessage = Funciona millor quan els fitxers tenen menys d'1 GB uploadPageSizeMessage = Funciona millor quan els fitxers tenen menys d'1 GB
uploadPageBrowseButton = Trieu un fitxer de l'ordinador uploadPageBrowseButton = Trieu un fitxer de l'ordinador
.title = Trieu un fitxer de l'ordinador .title = Trieu un fitxer de l'ordinador
uploadPageBrowseButton1 = Seleccioneu el fitxer que voleu pujar
.title = Seleccioneu el fitxer que voleu pujar
uploadPageMultipleFilesAlert = Actualment no es permet pujar diversos fitxers ni una carpeta. uploadPageMultipleFilesAlert = Actualment no es permet pujar diversos fitxers ni una carpeta.
uploadPageBrowseButtonTitle = Puja el fitxer uploadPageBrowseButtonTitle = Puja el fitxer
uploadingPageHeader = S'està pujant el fitxer uploadingPageProgress = S'està pujant { $filename } ({ $size })
importingFile = S'està important… importingFile = S'està important…
verifyingFile = S'està verificant… verifyingFile = S'està verificant…
encryptingFile = S'està xifrant… encryptingFile = S'està xifrant…
@@ -50,6 +52,8 @@ downloadButtonLabel = Baixa
.title = Baixa .title = Baixa
downloadNotification = La baixada ha acabat. downloadNotification = La baixada ha acabat.
downloadFinish = Ha acabat la baixada downloadFinish = Ha acabat la baixada
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } de { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Proveu el Firefox Send sendYourFilesLink = Proveu el Firefox Send
.title = Proveu el Firefox Send .title = Proveu el Firefox Send

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Přesunutím souboru sem spustíte jeho nahrávání
uploadPageSizeMessage = Nahrávání funguje nejlépe pro soubory do velikosti 1 GB. uploadPageSizeMessage = Nahrávání funguje nejlépe pro soubory do velikosti 1 GB.
uploadPageBrowseButton = Vybrat soubor z počítače uploadPageBrowseButton = Vybrat soubor z počítače
.title = Výběr souboru z počítače .title = Výběr souboru z počítače
uploadPageBrowseButton1 = Zvolte soubor k nahrání
.title = Zvolte soubor k nahrání
uploadPageMultipleFilesAlert = Nahrávání více souborů najednou nebo celých složek zatím není podporováno. uploadPageMultipleFilesAlert = Nahrávání více souborů najednou nebo celých složek zatím není podporováno.
uploadPageBrowseButtonTitle = Nahrát soubor uploadPageBrowseButtonTitle = Nahrát soubor
uploadingPageHeader = Nahrávání vašeho souboru uploadingPageProgress = Nahrávání souboru { $filename } ({ $size })
importingFile = Probíhá import… importingFile = Probíhá import…
verifyingFile = Probíhá ověřování… verifyingFile = Probíhá ověřování…
encryptingFile = Probíhá šifrování… encryptingFile = Probíhá šifrování…
@@ -26,7 +28,7 @@ uploadingFileNotification = Upozornit, až bude nahrávání dokončeno.
uploadSuccessConfirmHeader = Připraveno k odeslání uploadSuccessConfirmHeader = Připraveno k odeslání
uploadSvgAlt uploadSvgAlt
.alt = Nahrát .alt = Nahrát
uploadSuccessTimingHeader = Platnost odkazu na váš souboru vyprší po jeho prvním stažení, nebo po 24 hodinách. uploadSuccessTimingHeader = Platnost odkazu na váš soubor vyprší po jeho prvním stažení, nebo po 24 hodinách.
copyUrlFormLabelWithName = Zkopírujte a sdílejte odkaz na váš soubor: { $filename } copyUrlFormLabelWithName = Zkopírujte a sdílejte odkaz na váš soubor: { $filename }
// Note: Title text for button should be the same. // Note: Title text for button should be the same.
copyUrlFormButton = Zkopírovat do schránky copyUrlFormButton = Zkopírovat do schránky
@@ -50,6 +52,8 @@ downloadButtonLabel = Stáhnout
.title = Stáhnout .title = Stáhnout
downloadNotification = Stahování bylo dokončeno. downloadNotification = Stahování bylo dokončeno.
downloadFinish = Stahování dokončeno downloadFinish = Stahování dokončeno
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } z { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Vyzkoušejte Firefox Send sendYourFilesLink = Vyzkoušejte Firefox Send
.title = Vyzkoušejte Firefox Send .title = Vyzkoušejte Firefox Send
@@ -67,6 +71,7 @@ expiredPageHeader = Platnost tohoto odkazu buď vypršela, nebo vůbec nikdy nee
notSupportedHeader = Váš prohlížeč není podporován. notSupportedHeader = Váš prohlížeč není podporován.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Bohužel tento prohlížeč nepodporuje technologii, kterou Firefox Send používá. Zkuste prosím jiný prohlížeč, doporučujeme Firefox! notSupportedDetail = Bohužel tento prohlížeč nepodporuje technologii, kterou Firefox Send používá. Zkuste prosím jiný prohlížeč, doporučujeme Firefox!
notSupportedLink = Proč není můj prohlížeč podporovaný?
notSupportedOutdatedDetail = Tato verze Firefoxu bohužel nepodporuje webovou technologii, která pohání Firefox Send. Musíte aktualizovat svůj prohlížeč. notSupportedOutdatedDetail = Tato verze Firefoxu bohužel nepodporuje webovou technologii, která pohání Firefox Send. Musíte aktualizovat svůj prohlížeč.
updateFirefox = Aktualizovat Firefox updateFirefox = Aktualizovat Firefox
downloadFirefoxButtonSub = Stáhnout zdarma downloadFirefoxButtonSub = Stáhnout zdarma

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Gollyngwch eich ffeiliau yma i gychwyn llwytho i fyny
uploadPageSizeMessage = Mae'n well cadw maint y ffeiliau o dan 1GB er mwyn iddo weithio ar ei orau. uploadPageSizeMessage = Mae'n well cadw maint y ffeiliau o dan 1GB er mwyn iddo weithio ar ei orau.
uploadPageBrowseButton = Dewiswch ffeil ar eich cyfrifiadur uploadPageBrowseButton = Dewiswch ffeil ar eich cyfrifiadur
.title = Dewiswch ffeil ar eich cyfrifiadur .title = Dewiswch ffeil ar eich cyfrifiadur
uploadPageBrowseButton1 = Dewiswch ffeil i'w llwytho i fyny
.title = Dewiswch ffeil i'w llwytho i fyny
uploadPageMultipleFilesAlert = Nid yw llwytho nifer lluosog o ffeilia neu ffolder yn cael ei gynnal ar hyn o bryd. uploadPageMultipleFilesAlert = Nid yw llwytho nifer lluosog o ffeilia neu ffolder yn cael ei gynnal ar hyn o bryd.
uploadPageBrowseButtonTitle = Llwytho ffeil i fyny uploadPageBrowseButtonTitle = Llwytho ffeil i fyny
uploadingPageHeader = Llwytho eich Ffeiliau i Fyny uploadingPageProgress = Llwytho $filename} i fyny ({ $size })
importingFile = Mewnforio… importingFile = Mewnforio…
verifyingFile = Wrthi'n gwirio… verifyingFile = Wrthi'n gwirio…
encryptingFile = Wrthi'n amgryptio… encryptingFile = Wrthi'n amgryptio…
@@ -50,6 +52,8 @@ downloadButtonLabel = Llwytho i Lawr
.title = Llwytho i Lawr .title = Llwytho i Lawr
downloadNotification = Mae eich llwytho wedi gorffen downloadNotification = Mae eich llwytho wedi gorffen
downloadFinish = Llwytho wedi Gorffen downloadFinish = Llwytho wedi Gorffen
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } o { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Profwch Firefox Send sendYourFilesLink = Profwch Firefox Send
.title = Profwch Firefox Send .title = Profwch Firefox Send
@@ -67,6 +71,7 @@ expiredPageHeader = Mae'r ddolen wedi dod i ben neu nad yw wedi bodoli erioed!
notSupportedHeader = Nid yw eich porwr yn cael ei gynnal. notSupportedHeader = Nid yw eich porwr yn cael ei gynnal.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Yn anffodus nid yw'r porwr hwn yn cynnal y technoleg gwe sy'n cynnal Firefox Send. Bydd angen i chi ddefnyddio porwr arall. Rydym ni'n argymell Firefox! notSupportedDetail = Yn anffodus nid yw'r porwr hwn yn cynnal y technoleg gwe sy'n cynnal Firefox Send. Bydd angen i chi ddefnyddio porwr arall. Rydym ni'n argymell Firefox!
notSupportedLink = Pam nad yw fy mhorwr yn cael ei gynnal?
notSupportedOutdatedDetail = Yn anffodus nid yw'r fersiwn yma o Firefox yn cynnal y technoleg gwe sy'n gyrru Firefox Send. Bydd angen i chi ddiweddaru eich porwr. notSupportedOutdatedDetail = Yn anffodus nid yw'r fersiwn yma o Firefox yn cynnal y technoleg gwe sy'n gyrru Firefox Send. Bydd angen i chi ddiweddaru eich porwr.
updateFirefox = Diweddaru Firefox updateFirefox = Diweddaru Firefox
downloadFirefoxButtonSub = Llwytho i Lawr am Ddim downloadFirefoxButtonSub = Llwytho i Lawr am Ddim

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Ziehen Sie eine Datei zum Hochladen hierher
uploadPageSizeMessage = Dateien unter 1 GB sorgen für erhöhte Zuverlässigkeit des Betriebs uploadPageSizeMessage = Dateien unter 1 GB sorgen für erhöhte Zuverlässigkeit des Betriebs
uploadPageBrowseButton = Wählen Sie eine Datei auf Ihrem Computer aus uploadPageBrowseButton = Wählen Sie eine Datei auf Ihrem Computer aus
.title = Wählen Sie eine Datei auf Ihrem Computer aus .title = Wählen Sie eine Datei auf Ihrem Computer aus
uploadPageBrowseButton1 = Datei zum Hochladen auswählen
.title = Datei zum Hochladen auswählen
uploadPageMultipleFilesAlert = Hochladen mehrerer Dateien oder eines Ordners wird derzeit nicht unterstützt. uploadPageMultipleFilesAlert = Hochladen mehrerer Dateien oder eines Ordners wird derzeit nicht unterstützt.
uploadPageBrowseButtonTitle = Datei hochladen uploadPageBrowseButtonTitle = Datei hochladen
uploadingPageHeader = Ihre Datei wird hochgeladen uploadingPageProgress = { $filename } ({ $size }) wird hochgeladen
importingFile = Wird importiert… importingFile = Wird importiert…
verifyingFile = Wird überprüft… verifyingFile = Wird überprüft…
encryptingFile = Wird verschlüsselt… encryptingFile = Wird verschlüsselt…
@@ -50,6 +52,8 @@ downloadButtonLabel = Herunterladen
.title = Herunterladen .title = Herunterladen
downloadNotification = Der Download wurde abgeschlossen. downloadNotification = Der Download wurde abgeschlossen.
downloadFinish = Download abgeschlossen downloadFinish = Download abgeschlossen
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } von { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Firefox Send ausprobieren sendYourFilesLink = Firefox Send ausprobieren
.title = Firefox Send ausprobieren .title = Firefox Send ausprobieren

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Śěgniśo swóju dataju sem, aby ju nagrał
uploadPageSizeMessage = Wužywajśo nejlěpje dataje, kótarež su mjeńše ako 1 GB za lěpšu spušćobnosć. uploadPageSizeMessage = Wužywajśo nejlěpje dataje, kótarež su mjeńše ako 1 GB za lěpšu spušćobnosć.
uploadPageBrowseButton = Wubjeŕśo dataju na swójom licadle uploadPageBrowseButton = Wubjeŕśo dataju na swójom licadle
.title = Wubjeŕśo dataju na swójom licadle .title = Wubjeŕśo dataju na swójom licadle
uploadPageBrowseButton1 = Wubjeŕśo dataju za nagraśe
.title = Wubjeŕśo dataju za nagraśe
uploadPageMultipleFilesAlert = Nagrawanje někotarych datajow abo zarědnika se tuchylu njepódpěra. uploadPageMultipleFilesAlert = Nagrawanje někotarych datajow abo zarědnika se tuchylu njepódpěra.
uploadPageBrowseButtonTitle = Dataju nagraś uploadPageBrowseButtonTitle = Dataju nagraś
uploadingPageHeader = Waša dataja se nagrawa uploadingPageProgress = { $filename } ({ $size }) se nagrawa
importingFile = Importěrujo se... importingFile = Importěrujo se...
verifyingFile = Pśespytujo se... verifyingFile = Pśespytujo se...
encryptingFile = Koděrujo se... encryptingFile = Koděrujo se...
@@ -50,6 +52,8 @@ downloadButtonLabel = Ześěgnuś
.title = Ześěgnuś .title = Ześěgnuś
downloadNotification = Wašo ześěgnjenje jo dokóńcone. downloadNotification = Wašo ześěgnjenje jo dokóńcone.
downloadFinish = Ześěgnjenje dokóńcone downloadFinish = Ześěgnjenje dokóńcone
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } z { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Firefox Send wopytaś sendYourFilesLink = Firefox Send wopytaś
.title = Firefox Send wopytaś .title = Firefox Send wopytaś
@@ -67,6 +71,7 @@ expiredPageHeader = Toś ten wótkaz jo spadnjony abo njejo nigda eksistěrował
notSupportedHeader = Waš wobglědowak se njepódpěra. notSupportedHeader = Waš wobglědowak se njepódpěra.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Bóžko toś ten wobglědowak webtechnologiju njepódpěra, na kótarejž Firefox Send bazěrujo. Musyśo drugi wobglědowak wužywaś. My Firefox dopórucujomy! notSupportedDetail = Bóžko toś ten wobglědowak webtechnologiju njepódpěra, na kótarejž Firefox Send bazěrujo. Musyśo drugi wobglědowak wužywaś. My Firefox dopórucujomy!
notSupportedLink = Cogodla se mój wobglědowak njepódpěra?
notSupportedOutdatedDetail = Bóžko toś ta wersija Firefox webtechnologiju njepódpěra, na kótarejž Firefox Send bazěrujo. Musyśo swój wobglědowak aktualizěrowaś. notSupportedOutdatedDetail = Bóžko toś ta wersija Firefox webtechnologiju njepódpěra, na kótarejž Firefox Send bazěrujo. Musyśo swój wobglědowak aktualizěrowaś.
updateFirefox = Firefox aktualizěrowaś updateFirefox = Firefox aktualizěrowaś
downloadFirefoxButtonSub = Dermotne ześěgnjenje downloadFirefoxButtonSub = Dermotne ześěgnjenje

View File

@@ -2,18 +2,24 @@
title = Firefox Send title = Firefox Send
siteSubtitle = πείραμα διαδικτύου siteSubtitle = πείραμα διαδικτύου
siteFeedback = Σχόλια siteFeedback = Σχόλια
uploadPageHeader = Ιδιωτική, κρυπτογραφημένη κοινή χρήση αρχείων
uploadPageExplainer = Στείλτε αρχεία μέσω ασφαλούς, ιδιωτικού και κρυπτογραφημένου συνδέσμου που λήγει αυτόματα ώστε να διασφαλίσετε ότι τα περιεχόμενά σας δεν θα παραμείνουν στο διαδίκτυο για πάντα.
uploadPageLearnMore = Μάθετε περισσότερα uploadPageLearnMore = Μάθετε περισσότερα
uploadPageDropMessage = Εναποθέστε το αρχείο σας εδώ για έναρξη μεταφόρτωσης uploadPageDropMessage = Εναποθέστε το αρχείο σας εδώ για έναρξη μεταφόρτωσης
uploadPageSizeMessage = Για περισσότερο αξιόπιστη λειτουργία, προτείνεται να διατηρήσετε το αρχείο κάτω από 1GB
uploadPageBrowseButton = Επιλέξτε αρχείο από τον υπολογιστή σας uploadPageBrowseButton = Επιλέξτε αρχείο από τον υπολογιστή σας
.title = Επιλέξτε αρχείο από τον υπολογιστή σας .title = Επιλέξτε αρχείο από τον υπολογιστή σας
uploadPageBrowseButton1 = Επιλέξτε ένα αρχείο για μεταφόρτωση
.title = Επιλέξτε ένα αρχείο για μεταφόρτωση
uploadPageMultipleFilesAlert = Η μεταφόρτωση πολλαπλών αρχείων ή φακέλου δεν υποστηρίζεται αυτή τη στιγμή. uploadPageMultipleFilesAlert = Η μεταφόρτωση πολλαπλών αρχείων ή φακέλου δεν υποστηρίζεται αυτή τη στιγμή.
uploadPageBrowseButtonTitle = Μεταφόρτωση αρχείου uploadPageBrowseButtonTitle = Μεταφόρτωση αρχείου
uploadingPageHeader = Γίνετε μεταφόρτωση του αρχείου σας uploadingPageProgress = Μεταφόρτωση του { $filename } ({ $size })
importingFile = Εισαγωγή… importingFile = Εισαγωγή…
verifyingFile = Επαλήθευση... verifyingFile = Επαλήθευση...
encryptingFile = Κρυπτογράφηση… encryptingFile = Κρυπτογράφηση…
decryptingFile = Αποκρυπτογράφηση… decryptingFile = Αποκρυπτογράφηση…
notifyUploadDone = Η μεταφόρτωσή σας ολοκληρώθηκε. notifyUploadDone = Η μεταφόρτωσή σας ολοκληρώθηκε.
uploadingPageMessage = Αφού μεταφορτωθούν τα αρχεία σας, θα μπορείτε να ορίσετε επιλογές λήξης.
uploadingPageCancel = Ακύρωση μεταφόρτωσης uploadingPageCancel = Ακύρωση μεταφόρτωσης
.title = Ακύρωση μεταφόρτωσης .title = Ακύρωση μεταφόρτωσης
uploadCancelNotification = Η μεταφόρτωσή σας ακυρώθηκε. uploadCancelNotification = Η μεταφόρτωσή σας ακυρώθηκε.
@@ -22,6 +28,8 @@ uploadingFileNotification = Ειδοποίηση όταν ολοκληρωθεί
uploadSuccessConfirmHeader = Έτοιμο για αποστολή uploadSuccessConfirmHeader = Έτοιμο για αποστολή
uploadSvgAlt uploadSvgAlt
.alt = Μεταφόρτωση .alt = Μεταφόρτωση
uploadSuccessTimingHeader = Ο σύνδεσμος του αρχείου σας θα λήξει έπειτα από 1 λήψη ή 24 ώρες.
copyUrlFormLabelWithName = Αντιγράψτε και μοιραστείτε τον σύνδεσμο για αποστολή του αρχείου σας : { $filename }
// Note: Title text for button should be the same. // Note: Title text for button should be the same.
copyUrlFormButton = Αντιγραφή στο πρόχειρο copyUrlFormButton = Αντιγραφή στο πρόχειρο
.title = Αντιγραφή στο πρόχειρο .title = Αντιγραφή στο πρόχειρο
@@ -37,23 +45,35 @@ downloadAltText
.alt = Λήψη .alt = Λήψη
downloadFileName = Λήψη του { $filename } downloadFileName = Λήψη του { $filename }
downloadFileSize = ({ $size }) downloadFileSize = ({ $size })
// Firefox Send is a brand name and should not be localized.
downloadMessage = Ο/Η φίλος/-η σας, σάς στέλνει ένα αρχείο με τη βοήθεια του Firefox Send, μιας υπηρεσίας που επιτρέπει τον διαμοιρασμό αρχείων μέσω ενός ασφαλούς, ιδιωτικού και κρυπτογραφημένου συνδέσμου που λήγει αυτόματα, ώστε να είστε σίγουροι ότι τα αρχεία σας δεν θα παραμείνουν στο διαδίκτυο για πάντα.
// Text and title used on the download link/button (indicates an action). // Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Λήψη downloadButtonLabel = Λήψη
.title = Λήψη .title = Λήψη
downloadNotification = Η λήψη σας ολοκληρώθηκε. downloadNotification = Η λήψη σας ολοκληρώθηκε.
downloadFinish = Η λήψη ολοκληρώθηκε downloadFinish = Η λήψη ολοκληρώθηκε
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } από { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Δοκιμάστε το Firefox Send sendYourFilesLink = Δοκιμάστε το Firefox Send
.title = Δοκιμάστε το Firefox Send .title = Δοκιμάστε το Firefox Send
downloadingPageProgress = Γίνεται λήψη του { $filename } ({ $size }) downloadingPageProgress = Γίνεται λήψη του { $filename } ({ $size })
downloadingPageMessage = Παρακαλώ αφήστε ανοικτή αυτή την καρτέλα όσο λαμβάνουμε και αποκρυπτογραφούμε το αρχείο σας.
errorAltText errorAltText
.alt = Σφάλμα μεταφόρτωσης .alt = Σφάλμα μεταφόρτωσης
errorPageHeader = Κάτι πήγε στραβά! errorPageHeader = Κάτι πήγε στραβά!
errorPageMessage = Παρουσιάστηκε σφάλμα κατά τη μεταφόρτωση του αρχείου. errorPageMessage = Παρουσιάστηκε σφάλμα κατά τη μεταφόρτωση του αρχείου.
errorPageLink = Αποστολή άλλου αρχείου errorPageLink = Αποστολή άλλου αρχείου
fileTooBig = Αυτό το αρχείο είναι πολύ μεγάλο για μεταφόρτωση. Πρέπει να είναι μικρότερο από { $size }.
linkExpiredAlt linkExpiredAlt
.alt = Ο σύνδεσμος έληξε .alt = Ο σύνδεσμος έληξε
expiredPageHeader = Αυτός ο σύνδεσμος έχει λήξει ή δεν υπήρξε ποτέ!
notSupportedHeader = Το πρόγραμμα περιήγησής σας δεν υποστηρίζεται. notSupportedHeader = Το πρόγραμμα περιήγησής σας δεν υποστηρίζεται.
// Firefox Send is a brand name and should not be localized.
notSupportedDetail = Δυστυχώς, αυτό το πρόγραμμα περιήγησης δεν υποστηρίζει την τεχνολογία ιστού στην οποία βασίζεται το Firefox Send. Θα πρέπει να δοκιμάσετε ένα άλλο πρόγραμμα περιήγησης. Προτείνουμε το Firefox!
notSupportedLink = Γιατί δεν υποστηρίζεται το πρόγραμμα περιήγησής μου;
notSupportedOutdatedDetail = Δυστυχώς, αυτή η έκδοση του Firefox δεν υποστηρίζει την τεχνολογία ιστού στην οποία βασίζεται το Firefox Send. Πρέπει να ενημερώσετε το πρόγραμμα περιήγησής σας.
updateFirefox = Ενημέρωση Firefox
downloadFirefoxButtonSub = Δωρεάν λήψη downloadFirefoxButtonSub = Δωρεάν λήψη
uploadedFile = Αρχείο uploadedFile = Αρχείο
copyFileList = Αντιγραφή URL copyFileList = Αντιγραφή URL
@@ -62,6 +82,8 @@ expiryFileList = Λήγει σε
deleteFileList = Διαγραφή deleteFileList = Διαγραφή
nevermindButton = Μην ανησυχείτε nevermindButton = Μην ανησυχείτε
legalHeader = Όροι & απόρρητο legalHeader = Όροι & απόρρητο
legalNoticeTestPilot = Το Firefox Send αποτελεί προς το παρόν ένα πείραμα Test Pilot και υπόκειται στους <a>όρους υπηρεσίας</a> και την <a>πολιτική απορρήτου</a> του Test Pilot. Μπορείτε να μάθετε περισσότερα γι' αυτό το πείραμα και τη συλλογή δεδομένων <a>εδώ</a>.
legalNoticeMozilla = Η χρήση της ιστοσελίδας Firefox Send υπόκειται επίσης στην <a>πολιτική απορρήτου ιστοσελίδων</a> και τους <a>όρους χρήσης ιστοσελίδων</a> της Mozilla.
deletePopupText = Διαγραφή αρχείου; deletePopupText = Διαγραφή αρχείου;
deletePopupYes = Ναι deletePopupYes = Ναι
deletePopupCancel = Ακύρωση deletePopupCancel = Ακύρωση

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Drop your file here to start uploading
uploadPageSizeMessage = For the most reliable operation, its best to keep your file under 1GB uploadPageSizeMessage = For the most reliable operation, its best to keep your file under 1GB
uploadPageBrowseButton = Select a file on your computer uploadPageBrowseButton = Select a file on your computer
.title = Select a file on your computer .title = Select a file on your computer
uploadPageBrowseButton1 = Select a file to upload
.title = Select a file to upload
uploadPageMultipleFilesAlert = Uploading multiple files or a folder is currently not supported. uploadPageMultipleFilesAlert = Uploading multiple files or a folder is currently not supported.
uploadPageBrowseButtonTitle = Upload file uploadPageBrowseButtonTitle = Upload file
uploadingPageHeader = Uploading Your File uploadingPageProgress = Uploading { $filename } ({ $size })
importingFile = Importing… importingFile = Importing…
verifyingFile = Verifying… verifyingFile = Verifying…
encryptingFile = Encrypting… encryptingFile = Encrypting…
@@ -50,6 +52,8 @@ downloadButtonLabel = Download
.title = Download .title = Download
downloadNotification = Your download has completed. downloadNotification = Your download has completed.
downloadFinish = Download Complete downloadFinish = Download Complete
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } of { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Try Firefox Send sendYourFilesLink = Try Firefox Send
.title = Try Firefox Send .title = Try Firefox Send

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Arrastrá el archivo hasta acá para empezar a subir
uploadPageSizeMessage = Para una operación más confiable, es mejor que el archivo tenga menos de 1GB uploadPageSizeMessage = Para una operación más confiable, es mejor que el archivo tenga menos de 1GB
uploadPageBrowseButton = Seleccioná un archivo en tu computadora uploadPageBrowseButton = Seleccioná un archivo en tu computadora
.title = Seleccioná un archivo en tu computadora .title = Seleccioná un archivo en tu computadora
uploadPageBrowseButton1 = Seleccioná un archivo para subir
.title = Seleccioná un archivo para subir
uploadPageMultipleFilesAlert = Cargar múltiples archivos o una carpeta todavía no está soportado. uploadPageMultipleFilesAlert = Cargar múltiples archivos o una carpeta todavía no está soportado.
uploadPageBrowseButtonTitle = Subir archivo uploadPageBrowseButtonTitle = Subir archivo
uploadingPageHeader = Subiendo el archivo uploadingPageProgress = Subiendo { $filename } ({ $size })
importingFile = Importando… importingFile = Importando…
verifyingFile = Verificando… verifyingFile = Verificando…
encryptingFile = Cifrando… encryptingFile = Cifrando…
@@ -50,6 +52,8 @@ downloadButtonLabel = Descargar
.title = Descargar .title = Descargar
downloadNotification = La descarga se completó. downloadNotification = La descarga se completó.
downloadFinish = Descarga completa downloadFinish = Descarga completa
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } de { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Probá Firefox Send sendYourFilesLink = Probá Firefox Send
.title = Probá Firefox Send .title = Probá Firefox Send
@@ -67,6 +71,7 @@ expiredPageHeader = ¡Este enlace ha expirado o nunca existió en primer lugar!
notSupportedHeader = El navegador no está soportado. notSupportedHeader = El navegador no está soportado.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Desafortunadamente este navegador no soporta la tecnología web que necesita Firefox Send. Deberías probar otro navegador. ¡Te recomendamos Firefox! notSupportedDetail = Desafortunadamente este navegador no soporta la tecnología web que necesita Firefox Send. Deberías probar otro navegador. ¡Te recomendamos Firefox!
notSupportedLink = ¿Por qué mi navegador no está soportado?
notSupportedOutdatedDetail = Desafortunadamente esta versión de Firefox no soporta la tecnología web que necesita Firefox Send. Necesitás actualizar el navegador. notSupportedOutdatedDetail = Desafortunadamente esta versión de Firefox no soporta la tecnología web que necesita Firefox Send. Necesitás actualizar el navegador.
updateFirefox = Actualizar Firefox updateFirefox = Actualizar Firefox
downloadFirefoxButtonSub = Descarga gratuita downloadFirefoxButtonSub = Descarga gratuita
@@ -75,6 +80,7 @@ copyFileList = Copiar URL
// expiryFileList is used as a column header // expiryFileList is used as a column header
expiryFileList = Expira en expiryFileList = Expira en
deleteFileList = Borrar deleteFileList = Borrar
nevermindButton = No importa
legalHeader = Términos y privacidad legalHeader = Términos y privacidad
legalNoticeTestPilot = Firefox Send es actualmente un experimento de Test Pilot y está sujeto a los <a>términos de servicio</a> y la <a>nota de privacidad</a> de Test Pilot. Podés conocer más sobre este experimento y su recolección de datos <a>aquí</a>. legalNoticeTestPilot = Firefox Send es actualmente un experimento de Test Pilot y está sujeto a los <a>términos de servicio</a> y la <a>nota de privacidad</a> de Test Pilot. Podés conocer más sobre este experimento y su recolección de datos <a>aquí</a>.
legalNoticeMozilla = El uso del sitio web de Firefox Send también está sujeto a la <a>nota de privacidad de sitios web</a> y los <a>términos de uso de sitios web</a> de Mozilla. legalNoticeMozilla = El uso del sitio web de Firefox Send también está sujeto a la <a>nota de privacidad de sitios web</a> y los <a>términos de uso de sitios web</a> de Mozilla.

View File

@@ -8,9 +8,12 @@ uploadPageLearnMore = Aprender más
uploadPageDropMessage = Suelta tu archivo aquí para empezar a subirlo uploadPageDropMessage = Suelta tu archivo aquí para empezar a subirlo
uploadPageSizeMessage = Para una operación más confiable, es mejor mantener el tamaño del archivo bajo 1 GB uploadPageSizeMessage = Para una operación más confiable, es mejor mantener el tamaño del archivo bajo 1 GB
uploadPageBrowseButton = Selecciona un archivo en tu computador uploadPageBrowseButton = Selecciona un archivo en tu computador
.title = Selecciona un archivo en tu computador
uploadPageBrowseButton1 = Selecciona un archivo a subir
.title = Selecciona un archivo a subir
uploadPageMultipleFilesAlert = Subir múltiples archivos o una carpeta actualmente no es posible. uploadPageMultipleFilesAlert = Subir múltiples archivos o una carpeta actualmente no es posible.
uploadPageBrowseButtonTitle = Subir archivo uploadPageBrowseButtonTitle = Subir archivo
uploadingPageHeader = Subiendo tu archivo uploadingPageProgress = Subiendo { $filename } ({ $size })
importingFile = Importando… importingFile = Importando…
verifyingFile = Verificando… verifyingFile = Verificando…
encryptingFile = Cifrando… encryptingFile = Cifrando…
@@ -18,6 +21,7 @@ decryptingFile = Descifrando…
notifyUploadDone = Tu subida ha terminado. notifyUploadDone = Tu subida ha terminado.
uploadingPageMessage = Una vez que tu archivo sea subido podrás ajustar las opciones de expiración. uploadingPageMessage = Una vez que tu archivo sea subido podrás ajustar las opciones de expiración.
uploadingPageCancel = Cancelar subida uploadingPageCancel = Cancelar subida
.title = Cancelar subida
uploadCancelNotification = Tu subida fue cancelada. uploadCancelNotification = Tu subida fue cancelada.
uploadingPageLargeFileMessage = Este archivo es grande y puede tardar un rato en subir. ¡Aprovecha de hacer algo mientras! uploadingPageLargeFileMessage = Este archivo es grande y puede tardar un rato en subir. ¡Aprovecha de hacer algo mientras!
uploadingFileNotification = Notificarme cuando la subida sea completada. uploadingFileNotification = Notificarme cuando la subida sea completada.
@@ -28,11 +32,14 @@ uploadSuccessTimingHeader = El enlace a tu archivo expirará tras 1 descarga o e
copyUrlFormLabelWithName = Copia y comparte el enlace para enviar tu archivo: { $filename } copyUrlFormLabelWithName = Copia y comparte el enlace para enviar tu archivo: { $filename }
// Note: Title text for button should be the same. // Note: Title text for button should be the same.
copyUrlFormButton = Copiar al portapapeles copyUrlFormButton = Copiar al portapapeles
.title = Copiar al portapapeles
copiedUrl = ¡Copiado! copiedUrl = ¡Copiado!
// Note: Title text for button should be the same. // Note: Title text for button should be the same.
deleteFileButton = Eliminar archivo deleteFileButton = Eliminar archivo
.title = Eliminar archivo
// Note: Title text for button should be the same. // Note: Title text for button should be the same.
sendAnotherFileLink = Enviar otro archivo sendAnotherFileLink = Enviar otro archivo
.title = Enviar otro archivo
// Alternative text used on the download link/button (indicates an action). // Alternative text used on the download link/button (indicates an action).
downloadAltText downloadAltText
.alt = Descargar .alt = Descargar
@@ -42,13 +49,18 @@ downloadFileSize = ({ $size })
downloadMessage = Tu amigo te está enviando un archivo con Firefox Send, un servicio que te permite compartir archivos con un enlace seguro, privado y cifrado que expira automáticamente para asegurar que tus cosas no queden en línea de por vida. downloadMessage = Tu amigo te está enviando un archivo con Firefox Send, un servicio que te permite compartir archivos con un enlace seguro, privado y cifrado que expira automáticamente para asegurar que tus cosas no queden en línea de por vida.
// Text and title used on the download link/button (indicates an action). // Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Descargar downloadButtonLabel = Descargar
.title = Descargar
downloadNotification = Tu descarga se completó. downloadNotification = Tu descarga se completó.
downloadFinish = Descarga completa downloadFinish = Descarga completa
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } de { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Probar Firefox Send sendYourFilesLink = Probar Firefox Send
.title = Probar Firefox Send
downloadingPageProgress = Descargando { $filename } ({ $size }) downloadingPageProgress = Descargando { $filename } ({ $size })
downloadingPageMessage = Por favor, deja esta pestaña abierta mientras recibimos tu archivo y lo desciframos. downloadingPageMessage = Por favor, deja esta pestaña abierta mientras recibimos tu archivo y lo desciframos.
errorAltText = Error de subida errorAltText
.alt = Error de subida
errorPageHeader = ¡Algo se fue a las pailas! errorPageHeader = ¡Algo se fue a las pailas!
errorPageMessage = Hubo un error al subir el archivo. errorPageMessage = Hubo un error al subir el archivo.
errorPageLink = Enviar otro archivo errorPageLink = Enviar otro archivo
@@ -59,6 +71,7 @@ expiredPageHeader = ¡Este enlace ha expirado o quizá jamás existió!
notSupportedHeader = Tu navegador no está soportado. notSupportedHeader = Tu navegador no está soportado.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Lamentablemente este navegador no soporta la tecnología web que potencia a Firefox Send. Deberás probar en otro navegador. ¡Recomendamos Firefox! notSupportedDetail = Lamentablemente este navegador no soporta la tecnología web que potencia a Firefox Send. Deberás probar en otro navegador. ¡Recomendamos Firefox!
notSupportedLink = ¿Por qué mi navegador no es soportado?
notSupportedOutdatedDetail = Lamentablemente esta versión de Firefox no soporta la tecnología web que potencia a Firefox Send. Deberás actualizar tu navegador. notSupportedOutdatedDetail = Lamentablemente esta versión de Firefox no soporta la tecnología web que potencia a Firefox Send. Deberás actualizar tu navegador.
updateFirefox = Actualizar Firefox updateFirefox = Actualizar Firefox
downloadFirefoxButtonSub = Descarga gratuita downloadFirefoxButtonSub = Descarga gratuita
@@ -69,10 +82,7 @@ expiryFileList = Expira en
deleteFileList = Eliminar deleteFileList = Eliminar
nevermindButton = Da lo mismo nevermindButton = Da lo mismo
legalHeader = Términos y privacidad legalHeader = Términos y privacidad
legalNoticeTestPilot = legalNoticeTestPilot = Firefox Send es actualmente un experimento de Test Pilot, y está sujeto a los <a>Términos del servicio</a> y la <a>Política de privacidad</a> de Test Pilot. Puedes aprender más sobre este experimento y su recolección de datos <a>aquí</a>.
Firefox Send es actualmente un experimento de Test Pilot, y está sujeto a los <a>Términos del servicio</a> y la <a>Política de privacidad</a> de Test Pilot. Puedes aprender más sobre este experimento y su recolección de datos <a>aquí</a>.
legalNoticeMozilla = El uso del sitio web de Firefox Send también está sujeto a la <a>Política de privacidad de sitios web</a> y los <a>Términos de uso de sitios web</a> de Mozilla. legalNoticeMozilla = El uso del sitio web de Firefox Send también está sujeto a la <a>Política de privacidad de sitios web</a> y los <a>Términos de uso de sitios web</a> de Mozilla.
deletePopupText = ¿Eliminar este archivo? deletePopupText = ¿Eliminar este archivo?
deletePopupYes = Sí deletePopupYes = Sí

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Suelta aquí tu archivo para empezar a subirlo
uploadPageSizeMessage = Para que la operación sea más segura, el archivo debería ocupar menos de 1GB uploadPageSizeMessage = Para que la operación sea más segura, el archivo debería ocupar menos de 1GB
uploadPageBrowseButton = Seleccionar un archivo en el equipo uploadPageBrowseButton = Seleccionar un archivo en el equipo
.title = Seleccionar un archivo en el equipo .title = Seleccionar un archivo en el equipo
uploadPageBrowseButton1 = Seleccionar un archivo para subir
.title = Seleccionar un archivo para subir
uploadPageMultipleFilesAlert = Aún no se pueden subir varios archivos o una carpeta. uploadPageMultipleFilesAlert = Aún no se pueden subir varios archivos o una carpeta.
uploadPageBrowseButtonTitle = Subir archivo uploadPageBrowseButtonTitle = Subir archivo
uploadingPageHeader = Subiendo archivo uploadingPageProgress = Subiendo { $filename } ({ $size })
importingFile = Imporando... importingFile = Imporando...
verifyingFile = Comprobando... verifyingFile = Comprobando...
encryptingFile = Encriptando... encryptingFile = Encriptando...
@@ -50,6 +52,8 @@ downloadButtonLabel = Descargar
.title = Descargar .title = Descargar
downloadNotification = Se completó la descarga. downloadNotification = Se completó la descarga.
downloadFinish = Descarga completa downloadFinish = Descarga completa
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } de { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Prueba Firefox Send sendYourFilesLink = Prueba Firefox Send
.title = Prueba Firefox Send .title = Prueba Firefox Send
@@ -67,6 +71,7 @@ expiredPageHeader = ¡El enlace ha caducado o nunca existió!
notSupportedHeader = Tu navegador no está admitido. notSupportedHeader = Tu navegador no está admitido.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Lamentablemente, este navegador no admite la tecnología web que necesita Firefox Send. Tendrás que probar otro navegador. ¡Te recomendamos Firefox! notSupportedDetail = Lamentablemente, este navegador no admite la tecnología web que necesita Firefox Send. Tendrás que probar otro navegador. ¡Te recomendamos Firefox!
notSupportedLink = ¿Por qué no se admite mi navegador?
notSupportedOutdatedDetail = Lamentablemente, esta versión de Firefox no admite la tecnología web que impulsa Firefox Send. Tendrás que actualizar tu navegador. notSupportedOutdatedDetail = Lamentablemente, esta versión de Firefox no admite la tecnología web que impulsa Firefox Send. Tendrás que actualizar tu navegador.
updateFirefox = Actualizar Firefox updateFirefox = Actualizar Firefox
downloadFirefoxButtonSub = Descarga gratuita downloadFirefoxButtonSub = Descarga gratuita

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Suelta aquí tu archivo para empezar a subirlo
uploadPageSizeMessage = Para que la operación sea más segura, el archivo debería ocupar menos de 1GB uploadPageSizeMessage = Para que la operación sea más segura, el archivo debería ocupar menos de 1GB
uploadPageBrowseButton = Selecciona un archivo de tu computadora uploadPageBrowseButton = Selecciona un archivo de tu computadora
.title = Selecciona un archivo de tu computadora .title = Selecciona un archivo de tu computadora
uploadPageBrowseButton1 = Seleccionar un archivo para subir
.title = Seleccionar un archivo para subir
uploadPageMultipleFilesAlert = Aún no se pueden subir varios archivos o una carpeta. uploadPageMultipleFilesAlert = Aún no se pueden subir varios archivos o una carpeta.
uploadPageBrowseButtonTitle = Subir archivo uploadPageBrowseButtonTitle = Subir archivo
uploadingPageHeader = Subiendo tu archivo uploadingPageProgress = Subiendo { $filename } ({ $size })
importingFile = Importando... importingFile = Importando...
verifyingFile = Verificando... verifyingFile = Verificando...
encryptingFile = Encriptando... encryptingFile = Encriptando...
@@ -50,6 +52,8 @@ downloadButtonLabel = Descargar
.title = Descargar .title = Descargar
downloadNotification = Tu descarga se ha completado downloadNotification = Tu descarga se ha completado
downloadFinish = Descarga completa downloadFinish = Descarga completa
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } de { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Prueba Firefox Send sendYourFilesLink = Prueba Firefox Send
.title = Prueba Firefox Send .title = Prueba Firefox Send
@@ -67,6 +71,7 @@ expiredPageHeader = ¡Este enlace ha caducado o nunca existió en primer lugar!
notSupportedHeader = Tu navegador no está soportado. notSupportedHeader = Tu navegador no está soportado.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Lamentablemente, este navegador no admite la tecnología web que necesita Firefox Send. Tendrás que probar otro navegador. ¡Te recomendamos Firefox! notSupportedDetail = Lamentablemente, este navegador no admite la tecnología web que necesita Firefox Send. Tendrás que probar otro navegador. ¡Te recomendamos Firefox!
notSupportedLink = ¿Por qué mi navegador no tiene soporte?
notSupportedOutdatedDetail = Lamentablemente esta versión de Firefox no soporta la tecnología web que potencia a Firefox Send. Deberás actualizar tu navegador. notSupportedOutdatedDetail = Lamentablemente esta versión de Firefox no soporta la tecnología web que potencia a Firefox Send. Deberás actualizar tu navegador.
updateFirefox = Actualizar Firefox updateFirefox = Actualizar Firefox
downloadFirefoxButtonSub = Descarga gratuita downloadFirefoxButtonSub = Descarga gratuita

View File

@@ -0,0 +1,25 @@
// Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = آزمایش وب
siteFeedback = بازخورد
downloadFirefoxButtonSub = دریافت رایگان
uploadedFile = پرونده‌
copyFileList = رونوشت از نشانی
// expiryFileList is used as a column header
expiryFileList = زمان انقضا
deleteFileList = حذف
nevermindButton = بیخیال
legalHeader = شرایط و حریم‌خصوصی
deletePopupText = حذف این پرونده؟
deletePopupYes = بله
deletePopupCancel = انصراف
deleteButtonHover
.title = حذف
copyUrlHover
.title = رونوشت از نشانی
footerLinkLegal = ملاحظات حقوقی
// Test Pilot is a proper name and should not be localized.
footerLinkAbout = درباره Test Pilot
footerLinkPrivacy = حریم‌خصوصی
footerLinkTerms = شرایط
footerLinkCookies = کوکی‌ها

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Déposez votre fichier ici pour lenvoyer
uploadPageSizeMessage = Pour un résultat fiable, il est conseillé dutiliser des fichiers de taille inférieure à 1 Go uploadPageSizeMessage = Pour un résultat fiable, il est conseillé dutiliser des fichiers de taille inférieure à 1 Go
uploadPageBrowseButton = Sélectionner un fichier sur lordinateur uploadPageBrowseButton = Sélectionner un fichier sur lordinateur
.title = Sélectionner un fichier sur lordinateur .title = Sélectionner un fichier sur lordinateur
uploadPageBrowseButton1 = Choisir un fichier à envoyer
.title = Choisir un fichier à envoyer
uploadPageMultipleFilesAlert = Lenvoi de plusieurs fichiers ou de dossiers nest pas pris en charge pour le moment. uploadPageMultipleFilesAlert = Lenvoi de plusieurs fichiers ou de dossiers nest pas pris en charge pour le moment.
uploadPageBrowseButtonTitle = Envoyer le fichier uploadPageBrowseButtonTitle = Envoyer le fichier
uploadingPageHeader = Envoi du fichier en cours uploadingPageProgress = Envoi en cours de { $filename } ({ $size })
importingFile = Importation… importingFile = Importation…
verifyingFile = Vérification… verifyingFile = Vérification…
encryptingFile = Chiffrement… encryptingFile = Chiffrement…
@@ -50,6 +52,8 @@ downloadButtonLabel = Télécharger
.title = Télécharger .title = Télécharger
downloadNotification = Le téléchargement est terminé. downloadNotification = Le téléchargement est terminé.
downloadFinish = Téléchargement terminé downloadFinish = Téléchargement terminé
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } sur { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Essayer Firefox Send sendYourFilesLink = Essayer Firefox Send
.title = Essayer Firefox Send .title = Essayer Firefox Send

View File

@@ -67,6 +67,7 @@ expiredPageHeader = Dizze keppeling is ferrûn of hat nea bestien!
notSupportedHeader = Jo browser wurdt net stipe. notSupportedHeader = Jo browser wurdt net stipe.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Spitigernôch stipet dizze browser de webtechnology dy't Firefox Send mooglik makket net. Jo moatte in oare browser probearje. Wy rekommandearje Firefox! notSupportedDetail = Spitigernôch stipet dizze browser de webtechnology dy't Firefox Send mooglik makket net. Jo moatte in oare browser probearje. Wy rekommandearje Firefox!
notSupportedLink = Wêrom wurdt myn browser net stipe?
notSupportedOutdatedDetail = Spitigernôch stipet dizze ferzje fan Firefox de webtechnology dy't Firefox Send mooflik makket net. Jo moatte jo browser fernije. notSupportedOutdatedDetail = Spitigernôch stipet dizze ferzje fan Firefox de webtechnology dy't Firefox Send mooflik makket net. Jo moatte jo browser fernije.
updateFirefox = Firefox fernije updateFirefox = Firefox fernije
downloadFirefoxButtonSub = Fergese download downloadFirefoxButtonSub = Fergese download

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Ćehńće swoju dataju sem, zo byšće ju nahrał
uploadPageSizeMessage = Wužiwajće najlěpje dataje, kotrež su mjeńše hač 1 GB za lěpšu spušćomnosć. uploadPageSizeMessage = Wužiwajće najlěpje dataje, kotrež su mjeńše hač 1 GB za lěpšu spušćomnosć.
uploadPageBrowseButton = Wubjerće dataju na swojim ličaku uploadPageBrowseButton = Wubjerće dataju na swojim ličaku
.title = Wubjerće dataju na swojim ličaku .title = Wubjerće dataju na swojim ličaku
uploadPageBrowseButton1 = Wubjerće dataju za nahraće
.title = Wubjerće dataju za nahraće
uploadPageMultipleFilesAlert = Nahrawanje wjacorych datajow abo rjadowaka so tuchwilu njepodpěruje. uploadPageMultipleFilesAlert = Nahrawanje wjacorych datajow abo rjadowaka so tuchwilu njepodpěruje.
uploadPageBrowseButtonTitle = Dataju nahrać uploadPageBrowseButtonTitle = Dataju nahrać
uploadingPageHeader = Waša dataja so nahrawa uploadingPageProgress = { $filename } ({ $size }) so nahrawa
importingFile = Importuje so... importingFile = Importuje so...
verifyingFile = Přepruwuje so... verifyingFile = Přepruwuje so...
encryptingFile = Zaklučuje so... encryptingFile = Zaklučuje so...
@@ -50,6 +52,8 @@ downloadButtonLabel = Sćahnyć
.title = Sćahnyć .title = Sćahnyć
downloadNotification = Waše sćehnjenje je dokónčene. downloadNotification = Waše sćehnjenje je dokónčene.
downloadFinish = Sćehnjenje dokónčene downloadFinish = Sćehnjenje dokónčene
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } z { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Firefox Send wupruwować sendYourFilesLink = Firefox Send wupruwować
.title = Firefox Send wupruwować .title = Firefox Send wupruwować
@@ -67,6 +71,7 @@ expiredPageHeader = Tutón wotkaz je spadnjeny abo njeje ženje eksistował!
notSupportedHeader = Waš wobhladowak so njepodpěruje. notSupportedHeader = Waš wobhladowak so njepodpěruje.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Bohužel tutón wobhladowak webtechnologiju njepodpěruje, na kotrejž Firefox Send bazuje. Dyrbiće druhi wobhladowak wužiwać. My Firefox doporučemy! notSupportedDetail = Bohužel tutón wobhladowak webtechnologiju njepodpěruje, na kotrejž Firefox Send bazuje. Dyrbiće druhi wobhladowak wužiwać. My Firefox doporučemy!
notSupportedLink = Čehodla so mój wobhladowak njepodpěruje?
notSupportedOutdatedDetail = Bohužel tuta wersija Firefox webtechnologiju njepodpěruje, na kotrejž Firefox Send bazuje. Dyrbiće swój wobhladowak aktualizować. notSupportedOutdatedDetail = Bohužel tuta wersija Firefox webtechnologiju njepodpěruje, na kotrejž Firefox Send bazuje. Dyrbiće swój wobhladowak aktualizować.
updateFirefox = Firefox aktualizować updateFirefox = Firefox aktualizować
downloadFirefoxButtonSub = Darmotne sćehnjenje downloadFirefoxButtonSub = Darmotne sćehnjenje

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Dobja ide a fájljait, és kezdjen feltölteni
uploadPageSizeMessage = A megbízható működés érdekében a legjobb, ha a fájlok 1 GB-nál kisebbek maradnak uploadPageSizeMessage = A megbízható működés érdekében a legjobb, ha a fájlok 1 GB-nál kisebbek maradnak
uploadPageBrowseButton = Válasszon egy fájlt a számítógépén uploadPageBrowseButton = Válasszon egy fájlt a számítógépén
.title = Válasszon egy fájlt a számítógépén .title = Válasszon egy fájlt a számítógépén
uploadPageBrowseButton1 = Válassza ki a feltöltendő fájlt
.title = Válassza ki a feltöltendő fájlt
uploadPageMultipleFilesAlert = Több fájl vagy mappa feltöltése pillanatnyilag nem támogatott. uploadPageMultipleFilesAlert = Több fájl vagy mappa feltöltése pillanatnyilag nem támogatott.
uploadPageBrowseButtonTitle = Fájl feltöltése uploadPageBrowseButtonTitle = Fájl feltöltése
uploadingPageHeader = A fájlja feltöltése uploadingPageProgress = { $filename } ({ $size }) feltöltése
importingFile = Importálás… importingFile = Importálás…
verifyingFile = Ellenőrzés… verifyingFile = Ellenőrzés…
encryptingFile = Titkosítás… encryptingFile = Titkosítás…
@@ -50,6 +52,8 @@ downloadButtonLabel = Letöltés
.title = Letöltés .title = Letöltés
downloadNotification = A letöltés befejeződött. downloadNotification = A letöltés befejeződött.
downloadFinish = A letöltés befejeződött downloadFinish = A letöltés befejeződött
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } / { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Próbálja ki a Firefox Sendet sendYourFilesLink = Próbálja ki a Firefox Sendet
.title = Próbálja ki a Firefox Sendet .title = Próbálja ki a Firefox Sendet
@@ -67,6 +71,7 @@ expiredPageHeader = Ez a hivatkozás lejárt, vagy sosem létezett!
notSupportedHeader = A böngésző nem támogatott. notSupportedHeader = A böngésző nem támogatott.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Sajnos ez a böngésző nem támogatja a Firefox Send alapját képező webes technológiát. Egy másik böngészőben kell megpróbálnia. Mi a Firefoxot javasoljuk! notSupportedDetail = Sajnos ez a böngésző nem támogatja a Firefox Send alapját képező webes technológiát. Egy másik böngészőben kell megpróbálnia. Mi a Firefoxot javasoljuk!
notSupportedLink = Miért nem támogatott a böngészőm?
notSupportedOutdatedDetail = Sajnos a Firefox ezen verziója nem támogatja a Firefox Send alapját képező technológiát. Frissítenie kell a böngészőjét. notSupportedOutdatedDetail = Sajnos a Firefox ezen verziója nem támogatja a Firefox Send alapját képező technológiát. Frissítenie kell a böngészőjét.
updateFirefox = Firefox frissítése updateFirefox = Firefox frissítése
downloadFirefoxButtonSub = Ingyenes letöltés downloadFirefoxButtonSub = Ingyenes letöltés

View File

@@ -45,6 +45,9 @@ downloadFileName = Unduh { $filename }
downloadFileSize = ({ $size }) downloadFileSize = ({ $size })
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
downloadMessage = Teman Anda mengirimkan berkas dengan Firefox Send, layanan yang memungkinkan Anda berbagi berkas dengan tautan yang aman, pribadi, dan terenkripsi yang secara otomatis berakhir untuk memastikan berkas Anda tidak daring selamanya. downloadMessage = Teman Anda mengirimkan berkas dengan Firefox Send, layanan yang memungkinkan Anda berbagi berkas dengan tautan yang aman, pribadi, dan terenkripsi yang secara otomatis berakhir untuk memastikan berkas Anda tidak daring selamanya.
// Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Unduh
.title = Unduh
downloadNotification = Unduhan Anda telah selesai. downloadNotification = Unduhan Anda telah selesai.
downloadFinish = Unduhan Selesai downloadFinish = Unduhan Selesai
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
@@ -64,6 +67,7 @@ expiredPageHeader = Tautan ini telah kedaluwarsa atau tidak pernah ada!
notSupportedHeader = Peramban Anda tidak mendukung. notSupportedHeader = Peramban Anda tidak mendukung.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Sayangnya peramban ini tidak mendukung teknologi web yang menggerakkan Firefox Send. Anda perlu mencoba peramban lain. Kami merekomendasikan Firefox! notSupportedDetail = Sayangnya peramban ini tidak mendukung teknologi web yang menggerakkan Firefox Send. Anda perlu mencoba peramban lain. Kami merekomendasikan Firefox!
notSupportedLink = Mengapa peramban saya tidak didukung?
notSupportedOutdatedDetail = Sayangnya Firefox versi ini tidak mendukung teknologi web yang menggerakkan Firefox Send. Anda perlu memperbarui peramban Anda. notSupportedOutdatedDetail = Sayangnya Firefox versi ini tidak mendukung teknologi web yang menggerakkan Firefox Send. Anda perlu memperbarui peramban Anda.
updateFirefox = Perbarui Firefox updateFirefox = Perbarui Firefox
downloadFirefoxButtonSub = Unduh Gratis downloadFirefoxButtonSub = Unduh Gratis

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Trascina qui un file per caricarlo
uploadPageSizeMessage = Per evitare problemi è consigliabile caricare file di dimensione inferiore a 1 GB uploadPageSizeMessage = Per evitare problemi è consigliabile caricare file di dimensione inferiore a 1 GB
uploadPageBrowseButton = Seleziona un file sul computer uploadPageBrowseButton = Seleziona un file sul computer
.title = Seleziona un file sul computer .title = Seleziona un file sul computer
uploadPageBrowseButton1 = Seleziona un file da caricare
.title = Seleziona un file da caricare
uploadPageMultipleFilesAlert = Il caricamento di più file o cartelle non è attualmente supportato. uploadPageMultipleFilesAlert = Il caricamento di più file o cartelle non è attualmente supportato.
uploadPageBrowseButtonTitle = Carica file uploadPageBrowseButtonTitle = Carica file
uploadingPageHeader = Caricamento file uploadingPageProgress = Caricamento { $filename } ({ $size })
importingFile = Importazione in corso… importingFile = Importazione in corso…
verifyingFile = Verifica in corso… verifyingFile = Verifica in corso…
encryptingFile = Crittazione in corso… encryptingFile = Crittazione in corso…
@@ -50,6 +52,8 @@ downloadButtonLabel = Scarica
.title = Scarica .title = Scarica
downloadNotification = Download completato. downloadNotification = Download completato.
downloadFinish = Download completato downloadFinish = Download completato
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } di { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Prova Firefox Send sendYourFilesLink = Prova Firefox Send
.title = Prova Firefox Send .title = Prova Firefox Send
@@ -67,6 +71,7 @@ expiredPageHeader = Questo link è scaduto oppure non è mai esistito.
notSupportedHeader = Il browser in uso non è supportato. notSupportedHeader = Il browser in uso non è supportato.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Purtroppo questo browser non supporta le tecnologie web alla base di Firefox Send. Devi utilizzare un altro browser. Ti consigliamo Firefox! notSupportedDetail = Purtroppo questo browser non supporta le tecnologie web alla base di Firefox Send. Devi utilizzare un altro browser. Ti consigliamo Firefox!
notSupportedLink = Perché questo browser non risulta supportato?
notSupportedOutdatedDetail = Purtroppo questa versione di Firefox non supporta le tecnologie web alla base di Firefox Send. È necessario aggiornare il browser. notSupportedOutdatedDetail = Purtroppo questa versione di Firefox non supporta le tecnologie web alla base di Firefox Send. È necessario aggiornare il browser.
updateFirefox = Aggiorna Firefox updateFirefox = Aggiorna Firefox
downloadFirefoxButtonSub = Download gratuito downloadFirefoxButtonSub = Download gratuito

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = ここにファイルをドロップしてアップロ
uploadPageSizeMessage = 確実に処理できるよう、ファイルサイズは 1 GB 以下にすることを推奨します。 uploadPageSizeMessage = 確実に処理できるよう、ファイルサイズは 1 GB 以下にすることを推奨します。
uploadPageBrowseButton = コンピューター上のファイルを選択 uploadPageBrowseButton = コンピューター上のファイルを選択
.title = コンピューター上のファイルを選択 .title = コンピューター上のファイルを選択
uploadPageBrowseButton1 = アップロードするファイルを選択
.title = アップロードするファイルを選択
uploadPageMultipleFilesAlert = 今のところ複数ファイルやフォルダーのアップロードには対応していません。 uploadPageMultipleFilesAlert = 今のところ複数ファイルやフォルダーのアップロードには対応していません。
uploadPageBrowseButtonTitle = ファイルをアップロード uploadPageBrowseButtonTitle = ファイルをアップロード
uploadingPageHeader = ファイルをアップロードしています uploadingPageProgress = { $filename } ({ $size }) をアップロード
importingFile = インポート中... importingFile = インポート中...
verifyingFile = 検証中... verifyingFile = 検証中...
encryptingFile = 暗号化中... encryptingFile = 暗号化中...
@@ -50,11 +52,13 @@ downloadButtonLabel = ダウンロード
.title = ダウンロード .title = ダウンロード
downloadNotification = ダウンロードが完了しました。 downloadNotification = ダウンロードが完了しました。
downloadFinish = ダウンロード完了 downloadFinish = ダウンロード完了
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } / { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Firefox Send を試す sendYourFilesLink = Firefox Send を試す
.title = Firefox Send を試す .title = Firefox Send を試す
downloadingPageProgress = { $filename } ({ $size }) をダウンロードしています downloadingPageProgress = { $filename } ({ $size }) をダウンロードしています
downloadingPageMessage = ファイルの取得と号化が完了するまでこのタブを開いたままにしておいてください。 downloadingPageMessage = ファイルの取得と号化が完了するまでこのタブを開いたままにしておいてください。
errorAltText errorAltText
.alt = アップロードエラー .alt = アップロードエラー
errorPageHeader = 何か問題が発生しました。 errorPageHeader = 何か問題が発生しました。
@@ -67,6 +71,7 @@ expiredPageHeader = このリンクは期限切れとなったか元々存在し
notSupportedHeader = お使いのブラウザーには対応していません。 notSupportedHeader = お使いのブラウザーには対応していません。
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = 残念ながらお使いのブラウザーは Firefox Send が活用しているウェブ技術に対応していません。他のブラウザーで試してください。私たちは Firefox をお勧めします! notSupportedDetail = 残念ながらお使いのブラウザーは Firefox Send が活用しているウェブ技術に対応していません。他のブラウザーで試してください。私たちは Firefox をお勧めします!
notSupportedLink = なぜ私のブラウザには対応していないのでしょうか?
notSupportedOutdatedDetail = 残念ながらお使いのバージョンの Firefox は Firefox Send が活用しているウェブ技術に対応していません。ブラウザーを更新する必要があります。 notSupportedOutdatedDetail = 残念ながらお使いのバージョンの Firefox は Firefox Send が活用しているウェブ技術に対応していません。ブラウザーを更新する必要があります。
updateFirefox = Firefox を更新 updateFirefox = Firefox を更新
downloadFirefoxButtonSub = 無料ダウンロード downloadFirefoxButtonSub = 無料ダウンロード

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Zuɣeṛ afaylu-ik ar dagi akken ad tebduḍ asali
uploadPageSizeMessage = I ugmuḍ ufrin, yelha ad tesqedceḍ ifuyla daw n 1 GAṬ uploadPageSizeMessage = I ugmuḍ ufrin, yelha ad tesqedceḍ ifuyla daw n 1 GAṬ
uploadPageBrowseButton = Fren afaylu sef uselkim-ik uploadPageBrowseButton = Fren afaylu sef uselkim-ik
.title = Fren afaylu seg uselkim-ik .title = Fren afaylu seg uselkim-ik
uploadPageBrowseButton1 = Fren afaylu ad tazneḍ
.title = Fren afaylu ad tazneḍ
uploadPageMultipleFilesAlert = Asali n ddeqs n ifuyla neɣ ikaramen ur ittusefrak ara yakan. uploadPageMultipleFilesAlert = Asali n ddeqs n ifuyla neɣ ikaramen ur ittusefrak ara yakan.
uploadPageBrowseButtonTitle = Sali ifuyla uploadPageBrowseButtonTitle = Sali ifuyla
uploadingPageHeader = Asali n ufaylu-ik uploadingPageProgress = Tuzna n { $filename } ({ $size })
importingFile = Akter... importingFile = Akter...
verifyingFile = Asenqed... verifyingFile = Asenqed...
encryptingFile = Awgelhen... encryptingFile = Awgelhen...
@@ -50,6 +52,8 @@ downloadButtonLabel = Sider
.title = Sider .title = Sider
downloadNotification = Asider-ik yemmed. downloadNotification = Asider-ik yemmed.
downloadFinish = Asider yemmed downloadFinish = Asider yemmed
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } seg { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Ɛreḍ Firefox Send sendYourFilesLink = Ɛreḍ Firefox Send
.title = Ɛreḍ Firefox Send .title = Ɛreḍ Firefox Send
@@ -67,6 +71,7 @@ expiredPageHeader = Aseɣwen-agi yemmut neɣ wurǧin yella seg tazwara!
notSupportedHeader = Iminig-ik ur ittusefrak ara notSupportedHeader = Iminig-ik ur ittusefrak ara
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Ad nesḥissef imi iminig-ik ur isefrak ara tatiknulujit web iseqdac Firefox Send. Yessefk ad tesqedceḍ iminig-nniḍen. Seqdec Firefox! notSupportedDetail = Ad nesḥissef imi iminig-ik ur isefrak ara tatiknulujit web iseqdac Firefox Send. Yessefk ad tesqedceḍ iminig-nniḍen. Seqdec Firefox!
notSupportedLink = Ayγer iminig inu ur yettwasefrek ara?
notSupportedOutdatedDetail = Ad nesḥissef imilqem-agi n Firefox Firefox ur isefrak ara titiknulujiyin web yettwaseqdacen di Firefox Send. Yessefk ad tleqmeḍ iminig-ik. notSupportedOutdatedDetail = Ad nesḥissef imilqem-agi n Firefox Firefox ur isefrak ara titiknulujiyin web yettwaseqdacen di Firefox Send. Yessefk ad tleqmeḍ iminig-ik.
updateFirefox = Leqqem Firefox updateFirefox = Leqqem Firefox
downloadFirefoxButtonSub = Asider ilelli downloadFirefoxButtonSub = Asider ilelli

View File

@@ -0,0 +1,97 @@
// Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = 웹 실험
siteFeedback = 사용자 의견
uploadPageHeader = 개인적이고, 암호화된 파일 공유
uploadPageExplainer = 안전하고, 개인적이며, 암호화된 링크를 통해 파일을 공유하세요. 사용자의 파일이 더 이상 온라인 상에 남지 않도록 링크는 자동적으로 만료됩니다.
uploadPageLearnMore = 더 알아보기
uploadPageDropMessage = 파일을 끌어 놓아 업로드 시작
uploadPageSizeMessage = 확실한 작동을 위해서, 파일의 크기가 1GB보다 작은 것이 좋음
uploadPageBrowseButton = 컴퓨터의 파일을 선택
.title = 컴퓨터의 파일을 선택
uploadPageMultipleFilesAlert = 여러 개의 파일 또는 폴더를 업로드하는 것은 현재로선 지원되지 않습니다.
uploadPageBrowseButtonTitle = 파일 업로드
uploadingPageProgress = { $filename } ({ $size }) 업로드 중
importingFile = 가져오는 중…
verifyingFile = 확인하는 중…
encryptingFile = 암호화 중…
decryptingFile = 복호화 중…
notifyUploadDone = 업로드가 완료되었습니다.
uploadingPageMessage = 파일이 업로드 되고나서 만료 옵션을 설정할 수 있습니다.
uploadingPageCancel = 업로드 취소
.title = 업로드 취소
uploadCancelNotification = 업로드가 취소되었습니다.
uploadingPageLargeFileMessage = 이 파일은 크기가 커서 시간이 다소 걸릴 수 있습니다. 잠시만 기다려주세요!
uploadingFileNotification = 업로드가 완료되면 알림을 표시해 주세요.
uploadSuccessConfirmHeader = 보낼 준비 완료
uploadSvgAlt
.alt = 업로드
uploadSuccessTimingHeader = 이 파일의 링크는 한 번의 다운로드 후 또는 24시간이 지난 뒤에 만료됩니다.
copyUrlFormLabelWithName = 파일을 보내기 위해 이 링크를 복사하고 공유하세요: { $filename }
// Note: Title text for button should be the same.
copyUrlFormButton = 클립보드에 복사
.title = 클립보드에 복사
copiedUrl = 복사 완료!
// Note: Title text for button should be the same.
deleteFileButton = 파일 삭제
.title = 파일 삭제
// Note: Title text for button should be the same.
sendAnotherFileLink = 다른 파일 보내기
.title = 다른 파일 보내기
// Alternative text used on the download link/button (indicates an action).
downloadAltText
.alt = 다운로드
downloadFileName = { $filename } 다운로드
downloadFileSize = ({ $size })
// Firefox Send is a brand name and should not be localized.
downloadMessage = 당신의 친구가 Firefox Send를 통해 파일을 보내고 있습니다. 이 서비스는 안전하고, 개인적이며, 암호화된 링크를 통해 파일을 공유하는 서비스입니다. 사용자의 파일이 더 이상 온라인 상에 남지 않도록 링크는 자동적으로 만료됩니다.
// Text and title used on the download link/button (indicates an action).
downloadButtonLabel = 다운로드
.title = 다운로드
downloadNotification = 다운로드가 완료되었습니다.
downloadFinish = 다운로드 완료
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } / { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Firefox Send 써보기
.title = Firefox Send 써보기
downloadingPageProgress = { $filename } ({ $size }) 다운로드 중
downloadingPageMessage = 파일을 가져오고 복호화하는 동안 탭을 닫지 말아주세요.
errorAltText
.alt = 업로드 오류
errorPageHeader = 오류가 발생했습니다!
errorPageMessage = 파일을 업로드하는 도중 오류가 발생했습니다.
errorPageLink = 다른 파일 보내기
fileTooBig = 파일의 크기가 너무 큽니다. { $size } 보다 작아야 합니다.
linkExpiredAlt
.alt = 링크가 만료됨
expiredPageHeader = 이 링크는 만료되었거나 애초부터 존재하지 않았습니다!
notSupportedHeader = 이 브라우저는 지원되지 않습니다.
// Firefox Send is a brand name and should not be localized.
notSupportedDetail = 안타깝게도 이 브라우저는 Firefox Send에 사용되는 웹 기술을 지원하지 않습니다. 다른 브라우저로 다시 시도해주세요. Firefox를 추천합니다!
notSupportedLink = 왜 이 브라우저는 지원이 되지 않나요?
notSupportedOutdatedDetail = 안타깝게도 현재 브라우저 버전에서는 Firefox Send에 사용되는 웹 기술을 지원하지 않습니다. 브라우저 업데이트가 필요합니다.
updateFirefox = Firefox 업데이트
downloadFirefoxButtonSub = 무료 다운로드
uploadedFile = 파일
copyFileList = URL 복사
// expiryFileList is used as a column header
expiryFileList = 만료기한
deleteFileList = 삭제
nevermindButton = 괜찮습니다
legalHeader = 이용약관 & 개인정보 보호
legalNoticeTestPilot = Firefox Send는 현재 Test Pilot 실험 중이고, Test Pilot <a>이용 약관</a>과 <a>개인정보 보호공지</a>가 적용됩니다. 이 실험과 데이터 수집에 관해서는 <a>여기</a>에서 더 알아볼 수 있습니다.
legalNoticeMozilla = 또한, Firefox Send 웹사이트 사용에는 <a>웹사이트 개인정보 공지</a>와 <a>웹 사이트 이용약관</a>이 적용됩니다.
deletePopupText = 이 파일을 지우시겠습니까?
deletePopupYes = 예
deletePopupCancel = 아니오
deleteButtonHover
.title = 삭제
copyUrlHover
.title = URL 복사
footerLinkLegal = 법적 정보
// Test Pilot is a proper name and should not be localized.
footerLinkAbout = Test Pilot 정보
footerLinkPrivacy = 개인정보 보호
footerLinkTerms = 이용 약관
footerLinkCookies = 쿠키

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Letakkan fail anda di sini untuk mulakan memuat naik
uploadPageSizeMessage = Untuk operasi yang paling selamat, lebih baik pastikan fail anda itu kurang 1GB uploadPageSizeMessage = Untuk operasi yang paling selamat, lebih baik pastikan fail anda itu kurang 1GB
uploadPageBrowseButton = Pilih fail dalam komputer anda uploadPageBrowseButton = Pilih fail dalam komputer anda
.title = Pilih fail dalam komputer anda .title = Pilih fail dalam komputer anda
uploadPageBrowseButton1 = Pilih fail untuk dimuat naik
.title = Pilih fail untuk dimuat naik
uploadPageMultipleFilesAlert = Memuat naik pelbagai fail atau satu folder masih belum disokong. uploadPageMultipleFilesAlert = Memuat naik pelbagai fail atau satu folder masih belum disokong.
uploadPageBrowseButtonTitle = Muat naik fail uploadPageBrowseButtonTitle = Muat naik fail
uploadingPageHeader = Memuat naik Fail Anda uploadingPageProgress = Memuat naik { $filename } ({ $size })
importingFile = Mengimport… importingFile = Mengimport…
verifyingFile = Mengesahkan... verifyingFile = Mengesahkan...
encryptingFile = Mengenkripsi... encryptingFile = Mengenkripsi...
@@ -50,6 +52,8 @@ downloadButtonLabel = Muat turun
.title = Muat turun .title = Muat turun
downloadNotification = Muat turun anda sudah siap. downloadNotification = Muat turun anda sudah siap.
downloadFinish = Muat turun Selesai downloadFinish = Muat turun Selesai
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } daripada { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Cuba Firefox Send sendYourFilesLink = Cuba Firefox Send
.title = Cuba Firefox Send .title = Cuba Firefox Send

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Slipp din fil her for å starte opplastingen
uploadPageSizeMessage = For den mest problemfrie bruken, er det best å holde filen under 1 GB uploadPageSizeMessage = For den mest problemfrie bruken, er det best å holde filen under 1 GB
uploadPageBrowseButton = Velg en fil på din datamaskin uploadPageBrowseButton = Velg en fil på din datamaskin
.title = Velg en fil på din datamaskin .title = Velg en fil på din datamaskin
uploadPageBrowseButton1 = Velg en fil til å laste opp
.title = Velg en fil til å laste opp
uploadPageMultipleFilesAlert = Opplasting av flere filer eller en mappe støttes ikke for øyeblikket. uploadPageMultipleFilesAlert = Opplasting av flere filer eller en mappe støttes ikke for øyeblikket.
uploadPageBrowseButtonTitle = Last opp fil uploadPageBrowseButtonTitle = Last opp fil
uploadingPageHeader = Laster opp din fil uploadingPageProgress = Laster opp { $filename } ({ $size })
importingFile = Importerer… importingFile = Importerer…
verifyingFile = Verifiserer... verifyingFile = Verifiserer...
encryptingFile = Krypterer... encryptingFile = Krypterer...
@@ -50,6 +52,8 @@ downloadButtonLabel = Last ned
.title = Last ned .title = Last ned
downloadNotification = Nedlastingen er fullført. downloadNotification = Nedlastingen er fullført.
downloadFinish = Nedlastingen er fullført. downloadFinish = Nedlastingen er fullført.
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } av { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Prøv Firefox Send sendYourFilesLink = Prøv Firefox Send
.title = Prøv Firefox Send .title = Prøv Firefox Send
@@ -67,6 +71,7 @@ expiredPageHeader = Denne lenken er utløpt eller har aldri eksistert i utgangsp
notSupportedHeader = Din nettleser er ikke støttet. notSupportedHeader = Din nettleser er ikke støttet.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Dessverre støtter denne nettleseren ikke webteknologien som driver Firefox Send. Du må prøve en annen nettleser. Vi anbefaler Firefox! notSupportedDetail = Dessverre støtter denne nettleseren ikke webteknologien som driver Firefox Send. Du må prøve en annen nettleser. Vi anbefaler Firefox!
notSupportedLink = Hvorfor er ikke nettleseren min støttet?
notSupportedOutdatedDetail = Dessverre støtter ikke denne versjonen av Firefox netteknologien som driver Firefox Send. Du trenger å oppdatere nettleseren din. notSupportedOutdatedDetail = Dessverre støtter ikke denne versjonen av Firefox netteknologien som driver Firefox Send. Du trenger å oppdatere nettleseren din.
updateFirefox = Oppdater Firefox updateFirefox = Oppdater Firefox
downloadFirefoxButtonSub = Gratis nedlasting downloadFirefoxButtonSub = Gratis nedlasting

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Sleep uw bestand hiernaartoe om het te uploaden
uploadPageSizeMessage = Voor de meest betrouwbare werking kunt u uw bestand het beste onder de 1 GB houden uploadPageSizeMessage = Voor de meest betrouwbare werking kunt u uw bestand het beste onder de 1 GB houden
uploadPageBrowseButton = Selecteer een bestand op uw computer uploadPageBrowseButton = Selecteer een bestand op uw computer
.title = Selecteer een bestand op uw computer .title = Selecteer een bestand op uw computer
uploadPageBrowseButton1 = Selecteer een bestand om te uploaden
.title = Selecteer een bestand om te uploaden
uploadPageMultipleFilesAlert = Het uploaden van meerdere bestanden of een map wordt momenteel niet ondersteund. uploadPageMultipleFilesAlert = Het uploaden van meerdere bestanden of een map wordt momenteel niet ondersteund.
uploadPageBrowseButtonTitle = bestand uploaden uploadPageBrowseButtonTitle = bestand uploaden
uploadingPageHeader = Uw bestand wordt geüpload uploadingPageProgress = { $filename } ({ $size }) wordt geüpload
importingFile = Importeren… importingFile = Importeren…
verifyingFile = Verifiëren… verifyingFile = Verifiëren…
encryptingFile = Versleutelen… encryptingFile = Versleutelen…
@@ -50,6 +52,8 @@ downloadButtonLabel = Downloaden
.title = Downloaden .title = Downloaden
downloadNotification = Uw download is voltooid. downloadNotification = Uw download is voltooid.
downloadFinish = Downloaden voltooid downloadFinish = Downloaden voltooid
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } van { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Firefox Send proberen sendYourFilesLink = Firefox Send proberen
.title = Firefox Send proberen .title = Firefox Send proberen
@@ -67,6 +71,7 @@ expiredPageHeader = Deze koppeling is verlopen of heeft überhaupt nooit bestaan
notSupportedHeader = Uw browser wordt niet ondersteund. notSupportedHeader = Uw browser wordt niet ondersteund.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Helaas ondersteunt deze browser de webtechnologie die Firefox Send gebruikt niet. U dient een andere browser te proberen. Firefox wordt aanbevolen! notSupportedDetail = Helaas ondersteunt deze browser de webtechnologie die Firefox Send gebruikt niet. U dient een andere browser te proberen. Firefox wordt aanbevolen!
notSupportedLink = Waarom wordt mijn browser niet ondersteund?
notSupportedOutdatedDetail = Helaas ondersteunt deze versie van Firefox de webtechnologie die Firefox Send gebruikt niet. U dient uw browser bij te werken. notSupportedOutdatedDetail = Helaas ondersteunt deze versie van Firefox de webtechnologie die Firefox Send gebruikt niet. U dient uw browser bij te werken.
updateFirefox = Firefox bijwerken updateFirefox = Firefox bijwerken
downloadFirefoxButtonSub = Gratis download downloadFirefoxButtonSub = Gratis download

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Slepp fila di her for å starte opplastinga
uploadPageSizeMessage = For mest problemfrie bruk, er det best å halde fila under 1 GB uploadPageSizeMessage = For mest problemfrie bruk, er det best å halde fila under 1 GB
uploadPageBrowseButton = Vel ei fil på datamaskina di uploadPageBrowseButton = Vel ei fil på datamaskina di
.title = Vel ei fil på datamaskina di .title = Vel ei fil på datamaskina di
uploadPageBrowseButton1 = Vel ei fil å laste opp
.title = Vel ei fil å laste opp
uploadPageMultipleFilesAlert = Opplasting av fleire filer eller ei mappe er for tida ikkje støtta. uploadPageMultipleFilesAlert = Opplasting av fleire filer eller ei mappe er for tida ikkje støtta.
uploadPageBrowseButtonTitle = Last opp fil uploadPageBrowseButtonTitle = Last opp fil
uploadingPageHeader = Lastar opp fila di uploadingPageProgress = Lastar opp { $filename } ({ $size })
importingFile = Importerer… importingFile = Importerer…
verifyingFile = Stadfestar… verifyingFile = Stadfestar…
encryptingFile = Krypterer… encryptingFile = Krypterer…
@@ -50,6 +52,8 @@ downloadButtonLabel = Last ned
.title = Last ned .title = Last ned
downloadNotification = Nedlastinga er fullført. downloadNotification = Nedlastinga er fullført.
downloadFinish = Nedlastinga er fullført. downloadFinish = Nedlastinga er fullført.
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } av { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Prøv Firefox Send sendYourFilesLink = Prøv Firefox Send
.title = Prøv Firefox Send .title = Prøv Firefox Send

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Arraste o arquivo para cá para iniciar o envio
uploadPageSizeMessage = Para uma operação mais confiável, é melhor manter seu arquivo menor que 1GB uploadPageSizeMessage = Para uma operação mais confiável, é melhor manter seu arquivo menor que 1GB
uploadPageBrowseButton = Selecione um arquivo em seu computador uploadPageBrowseButton = Selecione um arquivo em seu computador
.title = Selecione um arquivo em seu computador .title = Selecione um arquivo em seu computador
uploadPageBrowseButton1 = Selecione um arquivo para carregar
.title = Selecione um arquivo para carregar
uploadPageMultipleFilesAlert = Enviar múltiplos arquivos ou uma pasta ainda não é suportado. uploadPageMultipleFilesAlert = Enviar múltiplos arquivos ou uma pasta ainda não é suportado.
uploadPageBrowseButtonTitle = Enviar arquivo uploadPageBrowseButtonTitle = Enviar arquivo
uploadingPageHeader = Enviando seu arquivo uploadingPageProgress = Enviando { $filename } ({ $size })
importingFile = Importando… importingFile = Importando…
verifyingFile = Verificando… verifyingFile = Verificando…
encryptingFile = Criptografando… encryptingFile = Criptografando…
@@ -40,21 +42,23 @@ sendAnotherFileLink = Enviar outro arquivo
.title = Enviar outro arquivo .title = Enviar outro arquivo
// Alternative text used on the download link/button (indicates an action). // Alternative text used on the download link/button (indicates an action).
downloadAltText downloadAltText
.alt = Download .alt = Baixar
downloadFileName = Download { $filename } downloadFileName = Baixar { $filename }
downloadFileSize = ({ $size }) downloadFileSize = ({ $size })
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
downloadMessage = Seu amigo está te enviando um arquivo através do Firefox Send, um serviço que permite compartilhar arquivos com segurança, privacidade e um link encriptado que automaticamente expira para garantir que suas coisas não permaneçam on-line eternamente. downloadMessage = Seu amigo está te enviando um arquivo através do Firefox Send, um serviço que permite compartilhar arquivos com um link seguro, privado e criptografado que automaticamente expira para garantir que suas coisas não permaneçam on-line eternamente.
// Text and title used on the download link/button (indicates an action). // Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Download downloadButtonLabel = Baixar
.title = Download .title = Baixar
downloadNotification = Seu download terminou. downloadNotification = Seu download terminou.
downloadFinish = Download completo downloadFinish = Download completo
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } de { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Experimente o Firefox Send sendYourFilesLink = Experimente o Firefox Send
.title = Experimente o Firefox Send .title = Experimente o Firefox Send
downloadingPageProgress = Baixando { $filename } ({ $size }) downloadingPageProgress = Baixando { $filename } ({ $size })
downloadingPageMessage = Por favor deixe essa aba aberta enquanto buscamos seu arquivo e o decriptamos. downloadingPageMessage = Por favor, deixe essa aba aberta enquanto buscamos seu arquivo e o descriptografamos.
errorAltText errorAltText
.alt = Erro no envio .alt = Erro no envio
errorPageHeader = Oops, ocorreu um erro! errorPageHeader = Oops, ocorreu um erro!
@@ -68,7 +72,7 @@ notSupportedHeader = Seu navegador não tem suporte.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Infelizmente esse navegador não suporta a tecnologia utilizada pelo Firefox Send. Tente com outro navegador. Nós recomendamos o Firefox! ;-) notSupportedDetail = Infelizmente esse navegador não suporta a tecnologia utilizada pelo Firefox Send. Tente com outro navegador. Nós recomendamos o Firefox! ;-)
notSupportedLink = Por que meu navegador não é suportado? notSupportedLink = Por que meu navegador não é suportado?
notSupportedOutdatedDetail = Infelizmente esta versão do Firefox não suporta a tecnologia web que faz o Firefox Send funcionar. Você precisa atualizar o seu navegador. notSupportedOutdatedDetail = Infelizmente essa versão do Firefox não suporta a tecnologia web que faz o Firefox Send funcionar. Você precisa atualizar o seu navegador.
updateFirefox = Atualizar o Firefox updateFirefox = Atualizar o Firefox
downloadFirefoxButtonSub = Download gratuito downloadFirefoxButtonSub = Download gratuito
uploadedFile = Arquivo uploadedFile = Arquivo
@@ -79,15 +83,15 @@ deleteFileList = Excluir
nevermindButton = Esqueça nevermindButton = Esqueça
legalHeader = Termos e privacidade legalHeader = Termos e privacidade
legalNoticeTestPilot = Firefox Send é um experimento do Test Pilot, e sujeito aos <a>Termos de Serviço</a> e <a>Políticas de Privacidade</a> do Test Pilot. Você pode aprender mais sobre esse experimento e a coleta de dados <a>aqui</a>. legalNoticeTestPilot = Firefox Send é um experimento do Test Pilot, e sujeito aos <a>Termos de Serviço</a> e <a>Políticas de Privacidade</a> do Test Pilot. Você pode aprender mais sobre esse experimento e a coleta de dados <a>aqui</a>.
legalNoticeMozilla = O uso do site Firefox Send também está sujeito a <a>Política de Privacidade</a> e <a>Websites Terms of Use</a> da Mozilla. legalNoticeMozilla = O uso do site Firefox Send também está sujeito a <a>Política de Privacidade</a> e ao <a>Termos de Uso de Sites</a> da Mozilla.
deletePopupText = Excluir este arquivo deletePopupText = Excluir este arquivo?
deletePopupYes = Sim deletePopupYes = Sim
deletePopupCancel = Cancelar deletePopupCancel = Cancelar
deleteButtonHover deleteButtonHover
.title = Excluir .title = Excluir
copyUrlHover copyUrlHover
.title = Copiar URL .title = Copiar URL
footerLinkLegal = Legal footerLinkLegal = Jurídico
// Test Pilot is a proper name and should not be localized. // Test Pilot is a proper name and should not be localized.
footerLinkAbout = Sobre o Test Pilot footerLinkAbout = Sobre o Test Pilot
footerLinkPrivacy = Privacidade footerLinkPrivacy = Privacidade

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Largue o seu ficheiro aqui para começar a carregar
uploadPageSizeMessage = Para uma operação mais confiável, é melhor manter o seu ficheiro abaixo de 1GB uploadPageSizeMessage = Para uma operação mais confiável, é melhor manter o seu ficheiro abaixo de 1GB
uploadPageBrowseButton = Selecionar um ficheiro no seu computador uploadPageBrowseButton = Selecionar um ficheiro no seu computador
.title = Selecionar um ficheiro no seu computador .title = Selecionar um ficheiro no seu computador
uploadPageBrowseButton1 = Selecione um ficheiro a enviar
.title = Selecione um ficheiro a enviar
uploadPageMultipleFilesAlert = Carregar múltiplos ficheiros ou uma pasta não é atualmente suportado. uploadPageMultipleFilesAlert = Carregar múltiplos ficheiros ou uma pasta não é atualmente suportado.
uploadPageBrowseButtonTitle = Carregar ficheiro uploadPageBrowseButtonTitle = Carregar ficheiro
uploadingPageHeader = A carregar o seu ficheiro uploadingPageProgress = A carregar { $filename } ({ $size })
importingFile = A importar... importingFile = A importar...
verifyingFile = A verificar... verifyingFile = A verificar...
encryptingFile = A encriptar... encryptingFile = A encriptar...
@@ -50,6 +52,8 @@ downloadButtonLabel = Descarregar
.title = Descarregar .title = Descarregar
downloadNotification = A sua descarga foi completada. downloadNotification = A sua descarga foi completada.
downloadFinish = Descarga completada downloadFinish = Descarga completada
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } de { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Tentar o Firefox Send sendYourFilesLink = Tentar o Firefox Send
.title = Tentar o Firefox Send .title = Tentar o Firefox Send

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Перетащите свой файл сюда, что
uploadPageSizeMessage = Для более надёжной работы сервиса, размер вашего файла не должен превышать 1ГБ. uploadPageSizeMessage = Для более надёжной работы сервиса, размер вашего файла не должен превышать 1ГБ.
uploadPageBrowseButton = Выбрать файл с моего компьютера uploadPageBrowseButton = Выбрать файл с моего компьютера
.title = Выбрать файл с моего компьютера .title = Выбрать файл с моего компьютера
uploadPageBrowseButton1 = Выбрать файл для загрузки
.title = Выбрать файл для загрузки
uploadPageMultipleFilesAlert = Загрузка нескольких файлов или папок в настоящее время не поддерживается. uploadPageMultipleFilesAlert = Загрузка нескольких файлов или папок в настоящее время не поддерживается.
uploadPageBrowseButtonTitle = Загрузить файл uploadPageBrowseButtonTitle = Загрузить файл
uploadingPageHeader = Загрузка вашего файла uploadingPageProgress = Загружаю { $filename } ({ $size })
importingFile = Импортирование... importingFile = Импортирование...
verifyingFile = Проверка... verifyingFile = Проверка...
encryptingFile = Шифрование... encryptingFile = Шифрование...
@@ -50,6 +52,8 @@ downloadButtonLabel = Скачать
.title = Скачать .title = Скачать
downloadNotification = Ваша загрузка завершена. downloadNotification = Ваша загрузка завершена.
downloadFinish = Загрузка завершена downloadFinish = Загрузка завершена
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } из { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Попробовать Firefox Send sendYourFilesLink = Попробовать Firefox Send
.title = Попробовать Firefox Send .title = Попробовать Firefox Send
@@ -67,6 +71,7 @@ expiredPageHeader = Это ссылка просрочена или никогд
notSupportedHeader = Ваш браузер не поддерживается. notSupportedHeader = Ваш браузер не поддерживается.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = К сожалению, этот браузер не поддерживает веб-технологию, благодаря которой работает Firefox Send. Ваш нужно попробовать использовать другой браузер. Мы рекомендуем Firefox! notSupportedDetail = К сожалению, этот браузер не поддерживает веб-технологию, благодаря которой работает Firefox Send. Ваш нужно попробовать использовать другой браузер. Мы рекомендуем Firefox!
notSupportedLink = Почему мой браузер не поддерживается?
notSupportedOutdatedDetail = К сожалению, эта версия Firefox не поддерживает веб-технологию, благодаря которой работает Firefox Send. Ваш нужно обновить свой браузер. notSupportedOutdatedDetail = К сожалению, эта версия Firefox не поддерживает веб-технологию, благодаря которой работает Firefox Send. Ваш нужно обновить свой браузер.
updateFirefox = Обновить Firefox updateFirefox = Обновить Firefox
downloadFirefoxButtonSub = Бесплатная загрузка downloadFirefoxButtonSub = Бесплатная загрузка

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Presunutím súboru sem začnete nahrávanie
uploadPageSizeMessage = Pre zaistenie čo najväčšej spoľahlivosti vám odporúčame nahrávať súbory menšie než 1GB. uploadPageSizeMessage = Pre zaistenie čo najväčšej spoľahlivosti vám odporúčame nahrávať súbory menšie než 1GB.
uploadPageBrowseButton = Vyberte súbor vo vašom počítači uploadPageBrowseButton = Vyberte súbor vo vašom počítači
.title = Vyberte súbor vo vašom počítači .title = Vyberte súbor vo vašom počítači
uploadPageBrowseButton1 = Vyberte súbor na nahratie
.title = Vyberte súbor na nahratie
uploadPageMultipleFilesAlert = Nahrávanie viacerých súborov alebo priečinkov momentálne nie je podporované. uploadPageMultipleFilesAlert = Nahrávanie viacerých súborov alebo priečinkov momentálne nie je podporované.
uploadPageBrowseButtonTitle = Nahrať súbor uploadPageBrowseButtonTitle = Nahrať súbor
uploadingPageHeader = Nahrávanie vášho súboru uploadingPageProgress = Nahrávanie súboru { $filename } ({ $size })
importingFile = Importuje sa… importingFile = Importuje sa…
verifyingFile = Overuje sa… verifyingFile = Overuje sa…
encryptingFile = Šifruje sa… encryptingFile = Šifruje sa…
@@ -50,6 +52,8 @@ downloadButtonLabel = Prevziať
.title = Prevziať .title = Prevziať
downloadNotification = Vaše preberanie bolo dokončené. downloadNotification = Vaše preberanie bolo dokončené.
downloadFinish = Preberanie bolo dokončené downloadFinish = Preberanie bolo dokončené
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } z { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Vyskúšajte Firefox Send sendYourFilesLink = Vyskúšajte Firefox Send
.title = Vyskúšajte Firefox Send .title = Vyskúšajte Firefox Send
@@ -67,6 +71,7 @@ expiredPageHeader = Platnosť tohto odkazu vypršala alebo daný odkaz nikdy nee
notSupportedHeader = Váš prehliadač nie je podporovaný. notSupportedHeader = Váš prehliadač nie je podporovaný.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Žiaľ, tento prehliadač nepodporuje webovú technológiu, ktorá poháňa službu Firefox Send. Budete musieť vyskúšať iný prehliadač. My vám odporúčame Firefox! notSupportedDetail = Žiaľ, tento prehliadač nepodporuje webovú technológiu, ktorá poháňa službu Firefox Send. Budete musieť vyskúšať iný prehliadač. My vám odporúčame Firefox!
notSupportedLink = Prečo nie je môj prehliadač podporovaný?
notSupportedOutdatedDetail = Žiaľ, táto verzia Firefoxu nepodporuje webovú technológiu, ktorá poháňa Firefox Send. Budete musieť aktualizovať svoj prehliadač. notSupportedOutdatedDetail = Žiaľ, táto verzia Firefoxu nepodporuje webovú technológiu, ktorá poháňa Firefox Send. Budete musieť aktualizovať svoj prehliadač.
updateFirefox = Aktualizovať Firefox updateFirefox = Aktualizovať Firefox
downloadFirefoxButtonSub = Prevziať zadarmo downloadFirefoxButtonSub = Prevziať zadarmo

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Tukaj spustite datoteko za začetek nalaganja
uploadPageSizeMessage = Za zanesljivo delovanje je najbolje, da datoteka ne presega 1 GB uploadPageSizeMessage = Za zanesljivo delovanje je najbolje, da datoteka ne presega 1 GB
uploadPageBrowseButton = Izberite datoteko na računalniku uploadPageBrowseButton = Izberite datoteko na računalniku
.title = Izberite datoteko na računalniku .title = Izberite datoteko na računalniku
uploadPageBrowseButton1 = Izberite datoteko za nalaganje
.title = Izberite datoteko za nalaganje
uploadPageMultipleFilesAlert = Nalaganje več datotek ali map trenutno ni podprto. uploadPageMultipleFilesAlert = Nalaganje več datotek ali map trenutno ni podprto.
uploadPageBrowseButtonTitle = Naloži datoteko uploadPageBrowseButtonTitle = Naloži datoteko
uploadingPageHeader = Nalaganje datoteke uploadingPageProgress = Nalaganje { $filename } ({ $size })
importingFile = Uvažanje … importingFile = Uvažanje …
verifyingFile = Preverjanje … verifyingFile = Preverjanje …
encryptingFile = Šifriranje ... encryptingFile = Šifriranje ...
@@ -50,6 +52,8 @@ downloadButtonLabel = Prenesi
.title = Prenesi .title = Prenesi
downloadNotification = Vaš prenos je končan. downloadNotification = Vaš prenos je končan.
downloadFinish = Prenos končan downloadFinish = Prenos končan
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } od { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Preskusite Firefox Send sendYourFilesLink = Preskusite Firefox Send
.title = Preskusite Firefox Send .title = Preskusite Firefox Send

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Превуците ваше датотеке овде д
uploadPageSizeMessage = За бољи рад предлажемо да датотека не буде већа од 1GB uploadPageSizeMessage = За бољи рад предлажемо да датотека не буде већа од 1GB
uploadPageBrowseButton = Изаберите датотеку на рачунару uploadPageBrowseButton = Изаберите датотеку на рачунару
.title = Изаберите датотеку на рачунару .title = Изаберите датотеку на рачунару
uploadPageBrowseButton1 = Изаберите датотеку за отпремање
.title = Изаберите датотеку за отпремање
uploadPageMultipleFilesAlert = Отпремање фасцикли или више датотека тренутно није подржано. uploadPageMultipleFilesAlert = Отпремање фасцикли или више датотека тренутно није подржано.
uploadPageBrowseButtonTitle = Отпреми датотеку uploadPageBrowseButtonTitle = Отпреми датотеку
uploadingPageHeader = Ваша датотека се отпрема uploadingPageProgress = Отпремам { $filename } ({ $size })
importingFile = Увозим… importingFile = Увозим…
verifyingFile = Потврђујем… verifyingFile = Потврђујем…
encryptingFile = Шифрујем… encryptingFile = Шифрујем…
@@ -50,6 +52,8 @@ downloadButtonLabel = Преузми
.title = Преузми .title = Преузми
downloadNotification = Ваше преузимање је завршено. downloadNotification = Ваше преузимање је завршено.
downloadFinish = Преузимање је завршено. downloadFinish = Преузимање је завршено.
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } од { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Испробајте Firefox Send sendYourFilesLink = Испробајте Firefox Send
.title = Испробајте Firefox Send .title = Испробајте Firefox Send

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Släpp filen här för att börja ladda upp
uploadPageSizeMessage = För den mest tillförlitliga driften är det bäst att hålla din fil under 1 GB uploadPageSizeMessage = För den mest tillförlitliga driften är det bäst att hålla din fil under 1 GB
uploadPageBrowseButton = Välj en fil på din dator uploadPageBrowseButton = Välj en fil på din dator
.title = Välj en fil på din dator .title = Välj en fil på din dator
uploadPageBrowseButton1 = Välj en fil att ladda upp
.title = Välj en fil att ladda upp
uploadPageMultipleFilesAlert = Överföring av flera filer eller en mapp stöds för närvarande inte. uploadPageMultipleFilesAlert = Överföring av flera filer eller en mapp stöds för närvarande inte.
uploadPageBrowseButtonTitle = Ladda upp fil uploadPageBrowseButtonTitle = Ladda upp fil
uploadingPageHeader = Överför din fil uploadingPageProgress = Laddar upp { $filename } ({ $size })
importingFile = Importerar… importingFile = Importerar…
verifyingFile = Verifierar… verifyingFile = Verifierar…
encryptingFile = Krypterar… encryptingFile = Krypterar…
@@ -50,6 +52,8 @@ downloadButtonLabel = Ladda ner
.title = Ladda ner .title = Ladda ner
downloadNotification = Din nedladdning har slutförts. downloadNotification = Din nedladdning har slutförts.
downloadFinish = Nedladdning klar downloadFinish = Nedladdning klar
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } av { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Testa Firefox Send sendYourFilesLink = Testa Firefox Send
.title = Testa Firefox Send .title = Testa Firefox Send
@@ -67,9 +71,8 @@ expiredPageHeader = Den här länken har upphört eller har aldrig existerat i f
notSupportedHeader = Din webbläsare stöds inte. notSupportedHeader = Din webbläsare stöds inte.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = Tyvärr stöder inte webbläsaren den webbteknologi som används av Firefox Send. Du måste försöka med en annan webbläsare. Vi rekommenderar Firefox! notSupportedDetail = Tyvärr stöder inte webbläsaren den webbteknologi som används av Firefox Send. Du måste försöka med en annan webbläsare. Vi rekommenderar Firefox!
notSupportedOutdatedDetail = notSupportedLink = Varför stöds inte min webbläsare?
Tyvärr stödjer den här versionen av Firefox inte webbtekniken som driver Firefox Send. Du måste uppdatera din webbläsare. notSupportedOutdatedDetail = Tyvärr stödjer den här versionen av Firefox inte webbtekniken som driver Firefox Send. Du måste uppdatera din webbläsare.
updateFirefox = Uppdatera Firefox updateFirefox = Uppdatera Firefox
downloadFirefoxButtonSub = Gratis nedladdning downloadFirefoxButtonSub = Gratis nedladdning
uploadedFile = Fil uploadedFile = Fil

View File

@@ -0,0 +1,83 @@
// Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = జాల ప్రయోగం
siteFeedback = అభిప్రాయం
uploadPageLearnMore = ఇంకా తెలుసుకోండి
uploadPageDropMessage = ఎగుమతిని ప్రారంభించడానికి మీ ఫైలును ఇక్కడ విడిచిపెట్టండి
uploadPageSizeMessage = అత్యంత నమ్మకమైన కార్యం కోసం, మీ ఫైలును 1GB కంటే తక్కువగా ఉంచడం ఉత్తమం
uploadPageBrowseButton = మీ కంప్యూటర్లో ఒక ఫైలును ఎంచుకోండి
.title = మీ కంప్యూటర్లో ఒక ఫైలును ఎంచుకోండి
uploadPageBrowseButtonTitle = ఫైలును ఎగుమతి చేయండి
uploadingPageHeader = మీ ఫైలు ఎగుమతి అవుతుంది
importingFile = దిగుమతవుతోంది...
verifyingFile = పరిశీలిస్తున్నది…
encryptingFile = గుప్తీకరిస్తోంది...
decryptingFile = వ్యక్తపరుస్తోంది...
notifyUploadDone = మీ ఎగుమతి పూర్తయింది.
uploadingPageMessage = మీ ఫైలును మీరు ఎగుమతి చేసిన తర్వాత గడువు ఎంపికలను సరిగా ఏర్పాటు చేయగలరు.
uploadingPageCancel = ఎగుమతి రద్దు చేయండి
.title = ఎగుమతి రద్దు చేయండి
uploadCancelNotification = మీ ఎగుమతి రద్దు చేయబడింది.
uploadingPageLargeFileMessage = ఈ ఫైలు పెద్దగా ఉంది అందువలన ఎగుమతి చేయడానికి కొంత సమయం పట్టవచ్చు. వేచి ఉండండి!
uploadingFileNotification = ఎగుమతి పూర్తయినప్పుడు నాకు తెలియచేయండి.
uploadSuccessConfirmHeader = పంపించడానికి సిద్ధంగా ఉంది
uploadSvgAlt
.alt = ఎగుమతి చేయండి
uploadSuccessTimingHeader = మీ ఫైలు లంకె గడువు 1 దిగుమతి తరువాత లేదా 24 గంటల తరువాత ముగుస్తుంది.
copyUrlFormLabelWithName = మీ ఫైల్ను పంపడానికి లంకెను నకలు చేయండి మరియు పంచండి: { $filename }
// Note: Title text for button should be the same.
copyUrlFormButton = క్లిప్బోర్డ్కు నకలు చేయండి
.title = క్లిప్బోర్డ్కు నకలు చేయండి
copiedUrl = నకలు చేయబడింది!
// Note: Title text for button should be the same.
deleteFileButton = ఫైలును తొలగించండి
.title = ఫైలును తొలగించండి
// Note: Title text for button should be the same.
sendAnotherFileLink = మరో ఫైలును పంపండి
.title = మరో ఫైలును పంపండి
// Alternative text used on the download link/button (indicates an action).
downloadAltText
.alt = దిగుమతి
downloadFileName = దిగుమతి { $filename }
downloadFileSize = ({ $size })
// Text and title used on the download link/button (indicates an action).
downloadButtonLabel = దిగుమతి
.title = దిగుమతి
downloadNotification = మీ దిగుమతి పూర్తయ్యింది.
downloadFinish = దిగుమతి పూర్తయింది
// Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Firefox sendను ప్రయత్నించండి
.title = Firefox sendను ప్రయత్నించండి
downloadingPageProgress = దిగుమతిచేస్తున్నది { $filename } ({ $size })
errorAltText
.alt = ఎగుమతిలో లోపం
errorPageHeader = ఏదో తప్పిదం జరిగింది!
errorPageMessage = ఫైల్ను ఎగుమతి చేయడంలో లోపం ఉంది.
errorPageLink = మరో ఫైలును పంపండి
linkExpiredAlt
.alt = లంకె గడువు ముగిసింది
expiredPageHeader = ఈ లంకె గడువు ముగిసింది లేదా ముందు ఎప్పుడూ ఉనికిలో లేదు!
notSupportedHeader = మీ విహారిణికి మద్దతు లేదు.
notSupportedLink = నా విహారిణికి ఎందుకు మద్దతు లేదు?
updateFirefox = Firefoxను నవీకరించు
downloadFirefoxButtonSub = ఉచిత దిగుమతులు
uploadedFile = దస్త్రం
copyFileList = URL నకలుతీయి
// expiryFileList is used as a column header
expiryFileList = ఇంతలో గడువుతీరును
deleteFileList = తొలగించు
nevermindButton = పర్వాలేదు
legalHeader = నిబంధనలు మరియు గోప్యత
deletePopupText = ఈ ఫైలును తొలగించాలా?
deletePopupYes = అవును
deletePopupCancel = రద్దుచేయి
deleteButtonHover
.title = తొలగించు
copyUrlHover
.title = URLను నకలు చేయండి
footerLinkLegal = చట్టపరమైన
// Test Pilot is a proper name and should not be localized.
footerLinkAbout = టెస్ట్ పైలట్ గురించి
footerLinkPrivacy = గోప్యత
footerLinkTerms = నియమాలు
footerLinkCookies = కుకీలు

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = Yüklemeyi başlatmak için dosyanızı buraya bırakın
uploadPageSizeMessage = Sorun yaşamamak adına dosyanızın 1 GBden küçük olmasını öneririz uploadPageSizeMessage = Sorun yaşamamak adına dosyanızın 1 GBden küçük olmasını öneririz
uploadPageBrowseButton = Bilgisayarınızdan bir dosya seçin uploadPageBrowseButton = Bilgisayarınızdan bir dosya seçin
.title = Bilgisayarınızdan bir dosya seçin .title = Bilgisayarınızdan bir dosya seçin
uploadPageBrowseButton1 = Yüklenecek dosyayı seçin
.title = Yüklenecek dosyayı seçin
uploadPageMultipleFilesAlert = Birden fazla dosya veya klasör yükleme şimdilik desteklenmiyor. uploadPageMultipleFilesAlert = Birden fazla dosya veya klasör yükleme şimdilik desteklenmiyor.
uploadPageBrowseButtonTitle = Dosyayı yükle uploadPageBrowseButtonTitle = Dosyayı yükle
uploadingPageHeader = Dosyanız yükleniyor uploadingPageProgress = { $filename } yükleniyor ({ $size })
importingFile = İçe aktarılıyor… importingFile = İçe aktarılıyor…
verifyingFile = Doğrulanıyor… verifyingFile = Doğrulanıyor…
encryptingFile = Şifreleniyor… encryptingFile = Şifreleniyor…
@@ -30,9 +32,11 @@ uploadSuccessTimingHeader = Dosyanız 1 kez indirildikten veya 24 saat geçtikte
copyUrlFormLabelWithName = { $filename } dosyanızı başkasına göndermek için aşağıdaki linki kopyalayın. copyUrlFormLabelWithName = { $filename } dosyanızı başkasına göndermek için aşağıdaki linki kopyalayın.
// Note: Title text for button should be the same. // Note: Title text for button should be the same.
copyUrlFormButton = Panoya kopyala copyUrlFormButton = Panoya kopyala
.title = Panoya kopyala
copiedUrl = Kopyalandı! copiedUrl = Kopyalandı!
// Note: Title text for button should be the same. // Note: Title text for button should be the same.
deleteFileButton = Dosyayı sil deleteFileButton = Dosyayı sil
.title = Dosyayı sil
// Note: Title text for button should be the same. // Note: Title text for button should be the same.
sendAnotherFileLink = Başka bir dosya daha gönder sendAnotherFileLink = Başka bir dosya daha gönder
.title = Başka bir dosya daha gönder .title = Başka bir dosya daha gönder
@@ -48,8 +52,11 @@ downloadButtonLabel = İndir
.title = İndir .title = İndir
downloadNotification = İndirme tamamlandı. downloadNotification = İndirme tamamlandı.
downloadFinish = İndirme tamamlandı downloadFinish = İndirme tamamlandı
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } / { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Firefox Sendi deneyin sendYourFilesLink = Firefox Sendi deneyin
.title = Firefox Sendi deneyin
downloadingPageProgress = { $filename } indiriliyor ({ $size }) downloadingPageProgress = { $filename } indiriliyor ({ $size })
downloadingPageMessage = Dosyanız indirilip şifresi çözülürken lütfen bu sekmeyi açık bırakın. downloadingPageMessage = Dosyanız indirilip şifresi çözülürken lütfen bu sekmeyi açık bırakın.
errorAltText errorAltText

View File

@@ -3,15 +3,17 @@ title = Firefox Send
siteSubtitle = веб-експеримент siteSubtitle = веб-експеримент
siteFeedback = Відгуки siteFeedback = Відгуки
uploadPageHeader = Приватний, зашифрований обмін файлами uploadPageHeader = Приватний, зашифрований обмін файлами
uploadPageExplainer = Надсилайте файли, використовуючи безпечні, приватні та зашифровані посилання, термін дії яких автоматично закінчується, щоб ваші файли не лишився в Інтернеті назавжди. uploadPageExplainer = Надсилайте файли, використовуючи безпечні, приватні та зашифровані посилання, термін дії яких автоматично закінчується, щоб ваші файли не лишилися в Інтернеті назавжди.
uploadPageLearnMore = Докладніше uploadPageLearnMore = Докладніше
uploadPageDropMessage = Перетягніть свій файл сюди, щоб почати вивантаження uploadPageDropMessage = Перетягніть свій файл сюди, щоб почати вивантаження
uploadPageSizeMessage = Для більш надійної роботи сервісу, розмір вашого файлу не має перевищувати 1ГБ. uploadPageSizeMessage = Для більш надійної роботи сервісу, розмір вашого файлу не має перевищувати 1ГБ.
uploadPageBrowseButton = Виберіть файл на комп'ютері uploadPageBrowseButton = Виберіть файл на комп'ютері
.title = Виберіть файл на комп'ютері .title = Виберіть файл на комп'ютері
uploadPageBrowseButton1 = Виберіть файл для вивантаження
.title = Виберіть файл для вивантаження
uploadPageMultipleFilesAlert = Вивантаження кількох файлів чи тек на даний момент не підтримується. uploadPageMultipleFilesAlert = Вивантаження кількох файлів чи тек на даний момент не підтримується.
uploadPageBrowseButtonTitle = Вивантажити файл uploadPageBrowseButtonTitle = Вивантажити файл
uploadingPageHeader = Вивантажуємо ваш файл uploadingPageProgress = Вивантажуємо { $filename } ({ $size })
importingFile = Імпортуємо... importingFile = Імпортуємо...
verifyingFile = Перевіряємо... verifyingFile = Перевіряємо...
encryptingFile = Шифруємо... encryptingFile = Шифруємо...
@@ -50,6 +52,8 @@ downloadButtonLabel = Завантажити
.title = Завантажити .title = Завантажити
downloadNotification = Ваше завантаження готово. downloadNotification = Ваше завантаження готово.
downloadFinish = Завантаження готово downloadFinish = Завантаження готово
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } з { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Спробуйте Firefox Send sendYourFilesLink = Спробуйте Firefox Send
.title = Спробуйте Firefox Send .title = Спробуйте Firefox Send
@@ -67,6 +71,7 @@ expiredPageHeader = Посилання не існує, або час його
notSupportedHeader = Ваш браузер не підтримується. notSupportedHeader = Ваш браузер не підтримується.
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = На жаль, цей браузер не підтримує веб-технологію, завдяки якій працює Firefox Send. Вам треба скористатися іншим браузером. Ми рекомендуємо Firefox! notSupportedDetail = На жаль, цей браузер не підтримує веб-технологію, завдяки якій працює Firefox Send. Вам треба скористатися іншим браузером. Ми рекомендуємо Firefox!
notSupportedLink = Чому мій браузер не підтримується?
notSupportedOutdatedDetail = На жаль, ця версія Firefox не підтримує веб-технологію, завдяки якій працює Firefox Send. Вам потрібно оновити свій браузер. notSupportedOutdatedDetail = На жаль, ця версія Firefox не підтримує веб-технологію, завдяки якій працює Firefox Send. Вам потрібно оновити свій браузер.
updateFirefox = Оновити Firefox updateFirefox = Оновити Firefox
downloadFirefoxButtonSub = Безкоштовне завантаження downloadFirefoxButtonSub = Безкоштовне завантаження

View File

@@ -0,0 +1,99 @@
// Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = Thử nghiệm trên web
siteFeedback = Phản hồi
uploadPageHeader = Chia sẻ tập tin riêng tư, được mã hóa
uploadPageExplainer = Gửi tập tin qua một liên kết an toàn, riêng tư, được mã hóa và tự động hết hạn để chắc chắn rằng dữ liệu của bạn không nằm mãi mãi trên Internet.
uploadPageLearnMore = Tìm hiểu thêm
uploadPageDropMessage = Kéo thả tập tin của bạn vào đây và bắt đầu tải lên
uploadPageSizeMessage = Để có thể hoạt động tốt nhất, hãy giữ tập tin của bạn dưới 1GB.
uploadPageBrowseButton = Chọn một tập tin từ máy tính
.title = Chọn một tập tin từ máy tính
uploadPageBrowseButton1 = Chọn tập tin để tải lên
.title = Chọn tập tin để tải lên
uploadPageMultipleFilesAlert = Tải lên nhiều tập tin một lúc hoặc tải lên một thư mục chưa được hỗ trợ.
uploadPageBrowseButtonTitle = Tải tập tin lên
uploadingPageProgress = Đang tải lên { $filename } ({ $size })
importingFile = Đang nhập...
verifyingFile = Đang xác thực...
encryptingFile = Đang mã hóa...
decryptingFile = Đang giải mã...
notifyUploadDone = Quá trình tải lên đã hoàn tất.
uploadingPageMessage = Một khi tập tin được tải lên, bạn sẽ có thể thiết lập các tùy chọn hết hạn của tập tin.
uploadingPageCancel = Hủy tải lên
.title = Hủy tải lên
uploadCancelNotification = Quá trình tải lên đã bị hủy.
uploadingPageLargeFileMessage = Tập tin này khá nặng và sẽ tốn một chút thời gian để tải lên. Chờ chút nhé!
uploadingFileNotification = Thông báo cho tôi khi tải lên hoàn tất.
uploadSuccessConfirmHeader = Đã sẵn sàng để Gửi
uploadSvgAlt
.alt = Tải lên
uploadSuccessTimingHeader = Liên kết đến tập tin của bạn sẽ hết hạn sau 1 lượt tải về hoặc trong 24 giờ.
copyUrlFormLabelWithName = Sao chép và chia sẻ liên kết để gửi tập tin của bạn: { $filename }
// Note: Title text for button should be the same.
copyUrlFormButton = Sao chép vào vùng nhớ tạm
.title = Sao chép vào vùng nhớ tạm
copiedUrl = Đã sao chép!
// Note: Title text for button should be the same.
deleteFileButton = Xóa tập tin
.title = Xóa tập tin
// Note: Title text for button should be the same.
sendAnotherFileLink = Gửi tập tin khác
.title = Gửi tập tin khác
// Alternative text used on the download link/button (indicates an action).
downloadAltText
.alt = Tải về
downloadFileName = Tải về { $filename }
downloadFileSize = ({ $size })
// Firefox Send is a brand name and should not be localized.
downloadMessage = Bạn của bạn đang gửi một tập tin thông qua Firefox Send, một dịch vụ cho phép bạn chia sẻ tập tin một cách an toàn, riêng tư, có liên kết được mã hóa và sẽ tự động hết hạn để chắc chắn rằng dữ liệu của bạn không nằm mãi mãi trên Internet.
// Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Tải về
.title = Tải về
downloadNotification = Quá trình tải về đã hoàn tất.
downloadFinish = Tải về hoàn tất
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } trong { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = Dùng thử Firefox Send
.title = Dùng thử Firefox Send
downloadingPageProgress = Đang tải về { $filename } ({ $size })
downloadingPageMessage = Vui lòng giữ cửa sổ này mở trong khi chúng tôi lấy tập tin và giải mã chúng.
errorAltText
.alt = Lỗi tải lên
errorPageHeader = Có gì đó không ổn!
errorPageMessage = Đã có lỗi trong quá trình tải lên tập tin.
errorPageLink = Gửi tập tin khác
fileTooBig = Tập tin này quá lớn để tải lên. Kích thước tập tin phải nhỏ hơn { $size }.
linkExpiredAlt
.alt = Liên kết đã hết hạn
expiredPageHeader = Liên kết này đã hết hạn hoặc chưa từng được sử dụng!
notSupportedHeader = Trình duyệt của bạn không được hỗ trợ.
// Firefox Send is a brand name and should not be localized.
notSupportedDetail = Thật không may trình duyệt này không hỗ trợ công nghệ đã tạo nên Firefox Send. Bạn cần thử với trình duyệt khác. Chúng tôi khuyên dùng Firefox!
notSupportedLink = Tại sao trình duyệt của tôi không được hỗ trợ?
notSupportedOutdatedDetail = Thật không may là phiên bản Firefox này không hỗ trợ công nghệ được sử dụng trong Firefox Send. Bạn cần cập nhật trình duyệt của bạn.
updateFirefox = Cập nhật Firefox
downloadFirefoxButtonSub = Tải về miễn phí
uploadedFile = Tập tin
copyFileList = Sao chép URL
// expiryFileList is used as a column header
expiryFileList = Hết hạn trong
deleteFileList = Xóa
nevermindButton = Đừng bận tâm
legalHeader = Điều khoản & Quyền riêng tư
legalNoticeTestPilot = Firefox Send hiện tại đang là một thử nghiệm Test Pilot, và phải tuân theo <a>Điều khoản dịch vụ</a> và <a>Lưu ý về Quyền riêng tư</a>. Bạn có thể tìm hiểu thêm về thử nghiệm này và dữ liệu được thu thập <a>tại đây</a>.
legalNoticeMozilla = Sử dụng trang web Firefox Send cũng phải tuân theo Mozilla's <a>Lưu ý về Quyền riêng tư của trang web</a> và <a>Điều khoản sử dụng của trang web</a>.
deletePopupText = Xóa tập tin này?
deletePopupYes = Đồng ý
deletePopupCancel = Hủy bỏ
deleteButtonHover
.title = Xóa
copyUrlHover
.title = Sao chép URL
footerLinkLegal = Pháp lý
// Test Pilot is a proper name and should not be localized.
footerLinkAbout = Về Test Pilot
footerLinkPrivacy = Quyền riêng tư
footerLinkTerms = Điều khoản
footerLinkCookies = Cookies

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = 拖放您的文件到此处以开始上传
uploadPageSizeMessage = 为保证运行稳定,建议文件大小不超过 1GB uploadPageSizeMessage = 为保证运行稳定,建议文件大小不超过 1GB
uploadPageBrowseButton = 选择一个您电脑上的文件 uploadPageBrowseButton = 选择一个您电脑上的文件
.title = 选择一个您电脑上的文件 .title = 选择一个您电脑上的文件
uploadPageBrowseButton1 = 选择一个要上传的文件
.title = 选择一个要上传的文件
uploadPageMultipleFilesAlert = 目前不支持上传多个文件或上传文件夹。 uploadPageMultipleFilesAlert = 目前不支持上传多个文件或上传文件夹。
uploadPageBrowseButtonTitle = 上传文件 uploadPageBrowseButtonTitle = 上传文件
uploadingPageHeader = 正在上传您的文件 uploadingPageProgress = 正在上传 { $filename } ({ $size })
importingFile = 正在导入… importingFile = 正在导入…
verifyingFile = 正在验证… verifyingFile = 正在验证…
encryptingFile = 正在加密… encryptingFile = 正在加密…
@@ -50,6 +52,8 @@ downloadButtonLabel = 下载
.title = 下载 .title = 下载
downloadNotification = 您的下载已完成。 downloadNotification = 您的下载已完成。
downloadFinish = 下载完成 downloadFinish = 下载完成
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } / { $totalSize })
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = 尝试 Firefox Send sendYourFilesLink = 尝试 Firefox Send
.title = 尝试 Firefox Send .title = 尝试 Firefox Send
@@ -67,6 +71,7 @@ expiredPageHeader = 此链接已过期或者从未生效。
notSupportedHeader = 不支持您的浏览器。 notSupportedHeader = 不支持您的浏览器。
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = 很可惜,您的浏览器不支持 Firefox Send 所使用的 Web 技术。请改用其他浏览器。我们推荐使用 Firefox notSupportedDetail = 很可惜,您的浏览器不支持 Firefox Send 所使用的 Web 技术。请改用其他浏览器。我们推荐使用 Firefox
notSupportedLink = 为什么不支持我的浏览器?
notSupportedOutdatedDetail = 很可惜,此版本的 Firefox 不支持 Firefox Send 所使用的 Web 技术。您需要更新浏览器才能使用它。 notSupportedOutdatedDetail = 很可惜,此版本的 Firefox 不支持 Firefox Send 所使用的 Web 技术。您需要更新浏览器才能使用它。
updateFirefox = 更新 Firefox updateFirefox = 更新 Firefox
downloadFirefoxButtonSub = 免费下载 downloadFirefoxButtonSub = 免费下载

View File

@@ -9,9 +9,11 @@ uploadPageDropMessage = 將檔案放到此處開始上傳
uploadPageSizeMessage = 為了讓系統能最穩定地執行,請盡量將檔案控制在 1GB 以下。 uploadPageSizeMessage = 為了讓系統能最穩定地執行,請盡量將檔案控制在 1GB 以下。
uploadPageBrowseButton = 選擇您電腦上的檔案 uploadPageBrowseButton = 選擇您電腦上的檔案
.title = 選擇您電腦上的檔案 .title = 選擇您電腦上的檔案
uploadPageBrowseButton1 = 選擇要上傳的檔案
.title = 選擇要上傳的檔案
uploadPageMultipleFilesAlert = 目前暫不支援上傳多個檔案或資料夾。 uploadPageMultipleFilesAlert = 目前暫不支援上傳多個檔案或資料夾。
uploadPageBrowseButtonTitle = 上傳檔案 uploadPageBrowseButtonTitle = 上傳檔案
uploadingPageHeader = 正在上傳檔案 uploadingPageProgress = 正在上傳 { $filename }{ $size }
importingFile = 匯入中… importingFile = 匯入中…
verifyingFile = 驗證中… verifyingFile = 驗證中…
encryptingFile = 加密中… encryptingFile = 加密中…
@@ -50,6 +52,8 @@ downloadButtonLabel = 下載
.title = 下載 .title = 下載
downloadNotification = 下載完成。 downloadNotification = 下載完成。
downloadFinish = 下載完成 downloadFinish = 下載完成
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = { $partialSize },共 { $totalSize }
// Firefox Send is a brand name and should not be localized. Title text for button should be the same. // Firefox Send is a brand name and should not be localized. Title text for button should be the same.
sendYourFilesLink = 試用 Firefox Send sendYourFilesLink = 試用 Firefox Send
.title = 試用 Firefox Send .title = 試用 Firefox Send
@@ -67,6 +71,7 @@ expiredPageHeader = 鏈結已失效,或根本不存在!
notSupportedHeader = 不支援您的瀏覽器。 notSupportedHeader = 不支援您的瀏覽器。
// Firefox Send is a brand name and should not be localized. // Firefox Send is a brand name and should not be localized.
notSupportedDetail = 很可惜,您使用的瀏覽器並不支援 Firefox Send 所需的 Web 技術。請改用其他瀏覽器,我們推薦使用 Firefox notSupportedDetail = 很可惜,您使用的瀏覽器並不支援 Firefox Send 所需的 Web 技術。請改用其他瀏覽器,我們推薦使用 Firefox
notSupportedLink = 為什麼我的瀏覽器不支援?
notSupportedOutdatedDetail = 很可惜,此版本的 Firefox 不支援 Firefox Send 所需的 Web 技術。請更新瀏覽器後再使用。 notSupportedOutdatedDetail = 很可惜,此版本的 Firefox 不支援 Firefox Send 所需的 Web 技術。請更新瀏覽器後再使用。
updateFirefox = 更新 Firefox updateFirefox = 更新 Firefox
downloadFirefoxButtonSub = 免費下載 downloadFirefoxButtonSub = 免費下載

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

View File

@@ -1,6 +1,7 @@
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const pkg = require('../package.json'); const pkg = require('../package.json');
const mkdirp = require('mkdirp');
let commit; let commit;
@@ -10,11 +11,11 @@ try {
// Whatever... // Whatever...
} }
const filename = path.join(__dirname, '..', 'public', 'version.json'); const filename = path.join(__dirname, '..', 'dist', 'public', 'version.json');
const filedata = { const filedata = {
commit, commit,
source: pkg.homepage, source: pkg.homepage,
version: process.env.CIRCLE_TAG || `v${pkg.version}` version: process.env.CIRCLE_TAG || `v${pkg.version}`
}; };
mkdirp.sync(path.dirname(filename));
fs.writeFileSync(filename, JSON.stringify(filedata, null, 2) + '\n'); fs.writeFileSync(filename, JSON.stringify(filedata, null, 2) + '\n');

View File

@@ -51,6 +51,11 @@ const conf = convict({
format: Boolean, format: Boolean,
default: false, default: false,
env: 'L10N_DEV' env: 'L10N_DEV'
},
base_url: {
format: 'url',
default: 'https://send.firefox.com',
env: 'BASE_URL'
} }
}); });

View File

@@ -4,13 +4,12 @@ const busboy = require('connect-busboy');
const path = require('path'); const path = require('path');
const bodyParser = require('body-parser'); const bodyParser = require('body-parser');
const helmet = require('helmet'); const helmet = require('helmet');
const bytes = require('bytes');
const conf = require('./config.js'); const conf = require('./config.js');
const storage = require('./storage.js'); const storage = require('./storage.js');
const Raven = require('raven'); const Raven = require('raven');
const crypto = require('crypto'); const crypto = require('crypto');
const fs = require('fs'); const fs = require('fs');
const version = require('../public/version.json'); const version = require('../dist/public/version.json');
if (conf.sentry_dsn) { if (conf.sentry_dsn) {
Raven.config(conf.sentry_dsn).install(); Raven.config(conf.sentry_dsn).install();
@@ -20,7 +19,7 @@ const mozlog = require('./log.js');
const log = mozlog('send.server'); const log = mozlog('send.server');
const STATIC_PATH = path.join(__dirname, '../public'); const STATIC_PATH = path.join(__dirname, '../dist/public');
const app = express(); const app = express();
@@ -39,14 +38,32 @@ function prodLangs() {
const availableLanguages = conf.l10n_dev ? allLangs() : prodLangs(); const availableLanguages = conf.l10n_dev ? allLangs() : prodLangs();
// dev middleware is broken at the moment because of how webpack builds the
// handlebars templates. Leaving the commented code here as a mark of shame.
// if (conf.env === 'development') {
// const webpack = require('webpack');
// const webpackDevMiddleware = require('webpack-dev-middleware');
// const config = require('../webpack.config.js');
// config.devtool = 'inline-source-map';
// const compiler = webpack(config);
// const wdm = webpackDevMiddleware(compiler, {
// publicPath: config.output.publicPath
// });
// app.use(wdm);
// }
app.set('views', 'dist/views/');
app.engine( app.engine(
'handlebars', 'handlebars',
exphbs({ exphbs({
defaultLayout: 'main', defaultLayout: 'main',
partialsDir: 'views/partials/', layoutsDir: 'dist/views/layouts',
helpers: { helpers: {
availableLanguages, availableLanguages,
l10nDev: conf.l10n_dev baseUrl: conf.base_url,
title: 'Firefox Send',
description:
'Encrypt and send files with a link that automatically expires to ensure your important documents dont stay online forever.'
} }
}) })
); );
@@ -87,6 +104,14 @@ app.use(
}) })
); );
app.use(bodyParser.json()); app.use(bodyParser.json());
app.use(
'/resources',
express.static(path.join(STATIC_PATH, 'resources'), {
setHeaders: function(res) {
res.set('Cache-Control', 'public, max-age=31536000, immutable');
}
})
);
app.use(express.static(STATIC_PATH)); app.use(express.static(STATIC_PATH));
app.get('/', (req, res) => { app.get('/', (req, res) => {
@@ -136,19 +161,21 @@ app.get('/exists/:id', async (req, res) => {
app.get('/download/:id', async (req, res) => { app.get('/download/:id', async (req, res) => {
const id = req.params.id; const id = req.params.id;
if (!validateID(id)) { if (!validateID(id)) {
res.sendStatus(404); res.status(404).render('notfound');
return; return;
} }
try { try {
const filename = await storage.filename(id); const efilename = await storage.filename(id);
const contentLength = await storage.length(id); const filename = decodeURIComponent(efilename);
const timeToExpiry = await storage.ttl(id); const filenameJson = JSON.stringify({ filename });
const sizeInBytes = await storage.length(id);
const ttl = await storage.ttl(id);
res.render('download', { res.render('download', {
filename: decodeURIComponent(filename), filename,
filesize: bytes(contentLength), filenameJson,
sizeInBytes: contentLength, sizeInBytes,
timeToExpiry: timeToExpiry ttl
}); });
} catch (e) { } catch (e) {
res.status(404).render('notfound'); res.status(404).render('notfound');
@@ -167,7 +194,7 @@ app.get('/assets/download/:id', async (req, res) => {
const contentLength = await storage.length(id); const contentLength = await storage.length(id);
res.writeHead(200, { res.writeHead(200, {
'Content-Disposition': `attachment; filename=${meta.filename}`, 'Content-Disposition': `attachment; filename=${meta.filename}`,
'Content-Type': 'application/octet-stream', 'Content-Type': meta.mimeType,
'Content-Length': contentLength, 'Content-Length': contentLength,
'X-File-Metadata': JSON.stringify(meta) 'X-File-Metadata': JSON.stringify(meta)
}); });
@@ -175,10 +202,7 @@ app.get('/assets/download/:id', async (req, res) => {
file_stream.on('end', async () => { file_stream.on('end', async () => {
try { try {
const err = await storage.forceDelete(id); await storage.forceDelete(id);
if (!err) {
log.info('Deleted:', id);
}
} catch (e) { } catch (e) {
log.info('DeleteError:', id); log.info('DeleteError:', id);
} }
@@ -208,7 +232,6 @@ app.post('/delete/:id', async (req, res) => {
try { try {
const err = await storage.delete(id, delete_token); const err = await storage.delete(id, delete_token);
if (!err) { if (!err) {
log.info('Deleted:', id);
res.sendStatus(200); res.sendStatus(200);
} }
} catch (e) { } catch (e) {
@@ -228,7 +251,6 @@ app.post('/upload', (req, res, next) => {
} }
if ( if (
!meta.hasOwnProperty('aad') ||
!meta.hasOwnProperty('id') || !meta.hasOwnProperty('id') ||
!meta.hasOwnProperty('filename') || !meta.hasOwnProperty('filename') ||
!validateIV(meta.id) !validateIV(meta.id)
@@ -238,36 +260,33 @@ app.post('/upload', (req, res, next) => {
} }
meta.delete = crypto.randomBytes(10).toString('hex'); meta.delete = crypto.randomBytes(10).toString('hex');
log.info('meta', meta);
req.pipe(req.busboy); req.pipe(req.busboy);
req.busboy.on('file', async (fieldname, file, filename) => { req.busboy.on(
log.info('Uploading:', newId); 'file',
async (fieldname, file, filename, encoding, mimeType) => {
try { try {
await storage.set(newId, file, filename, meta); meta.mimeType = mimeType || 'application/octet-stream';
await storage.set(newId, file, filename, meta);
const protocol = conf.env === 'production' ? 'https' : req.protocol; const protocol = conf.env === 'production' ? 'https' : req.protocol;
const url = `${protocol}://${req.get('host')}/download/${newId}/`; const url = `${protocol}://${req.get('host')}/download/${newId}/`;
res.json({ res.json({
url, url,
delete: meta.delete, delete: meta.delete,
id: newId id: newId
}); });
} catch (e) { } catch (e) {
if (e.message === 'limit') { if (e.message === 'limit') {
return res.sendStatus(413); return res.sendStatus(413);
}
res.sendStatus(500);
} }
res.sendStatus(500);
} }
}); );
req.on('close', async err => { req.on('close', async err => {
try { try {
const err = await storage.forceDelete(newId); await storage.forceDelete(newId);
if (!err) {
log.info('Deleted:', newId);
}
} catch (e) { } catch (e) {
log.info('DeleteError:', newId); log.info('DeleteError:', newId);
} }

View File

@@ -16,7 +16,7 @@ const redis_client = redis.createClient({
}); });
redis_client.on('error', err => { redis_client.on('error', err => {
log.info('Redis:', err); log.error('Redis:', err);
}); });
if (conf.s3_bucket) { if (conf.s3_bucket) {
@@ -155,6 +155,7 @@ function localDelete(id, delete_token) {
reject(); reject();
} else { } else {
redis_client.del(id); redis_client.del(id);
log.info('Deleted:', id);
resolve(fs.unlinkSync(path.join(__dirname, '../static', id))); resolve(fs.unlinkSync(path.join(__dirname, '../static', id)));
} }
}); });
@@ -201,7 +202,6 @@ function awsGet(id) {
try { try {
return s3.getObject(params).createReadStream(); return s3.getObject(params).createReadStream();
} catch (err) { } catch (err) {
log.info('GetFailed', 'Get Object from s3 failed.');
return null; return null;
} }
} }
@@ -222,7 +222,6 @@ function awsSet(newId, file, filename, meta) {
() => { () => {
redis_client.hmset(newId, meta); redis_client.hmset(newId, meta);
redis_client.expire(newId, conf.expire_seconds); redis_client.expire(newId, conf.expire_seconds);
log.info('awsUploadFinish', 'Upload Finished of ' + filename);
}, },
err => { err => {
if (hitLimit) { if (hitLimit) {
@@ -263,7 +262,7 @@ function awsForceDelete(id) {
s3.deleteObject(params, function(err, _data) { s3.deleteObject(params, function(err, _data) {
redis_client.del(id); redis_client.del(id);
err ? reject(err) : resolve(err); err ? reject(err) : resolve();
}); });
}); });
} }

View File

@@ -6,7 +6,7 @@ const driver = new webdriver.Builder().forBrowser('firefox').build();
driver.get(path.join('file:///', __dirname, '/frontend.test.html')); driver.get(path.join('file:///', __dirname, '/frontend.test.html'));
driver.wait(until.titleIs('Mocha Tests')); driver.wait(until.titleIs('Mocha Tests'));
driver.wait(until.titleMatches(/^[0-1]$/)); driver.wait(until.titleMatches(/^[0-9]$/));
driver.getTitle().then(title => { driver.getTitle().then(title => {
driver.quit().then(() => { driver.quit().then(() => {

View File

@@ -4,12 +4,10 @@ const FakeFile = window.FakeFile;
const assert = window.assert; const assert = window.assert;
const server = window.server; const server = window.server;
const hexToArray = window.hexToArray; const hexToArray = window.hexToArray;
const arrayToHex = window.arrayToHex;
const sinon = window.sinon; const sinon = window.sinon;
let file; let file;
let encryptedIV; let encryptedIV;
let fileHash;
let secretKey; let secretKey;
let originalBlob; let originalBlob;
@@ -59,28 +57,6 @@ describe('File Sender', function() {
}); });
}); });
it('Should get a hashing event emission', function() {
const file = new FakeFile('hello_world.txt', ['This is some data.']);
const fs = new FileSender(file);
let testHashing = true;
fs.on('hashing', isStillHashing => {
assert(!(!testHashing && isStillHashing));
testHashing = isStillHashing;
});
return fs
.upload()
.then(info => {
assert(info);
assert(!testHashing);
})
.catch(err => {
console.log(err, err.stack);
assert.fail();
});
});
it('Should get a encrypting event emission', function() { it('Should get a encrypting event emission', function() {
const file = new FakeFile('hello_world.txt', ['This is some data.']); const file = new FakeFile('hello_world.txt', ['This is some data.']);
const fs = new FileSender(file); const fs = new FileSender(file);
@@ -116,45 +92,40 @@ describe('File Sender', function() {
readRaw.onload = function(event) { readRaw.onload = function(event) {
const rawArray = new Uint8Array(this.result); const rawArray = new Uint8Array(this.result);
originalBlob = rawArray; originalBlob = rawArray;
window.crypto.subtle
window.crypto.subtle.digest('SHA-256', rawArray).then(hash => { .importKey(
fileHash = hash; 'jwk',
window.crypto.subtle {
.importKey( kty: 'oct',
'jwk', k: key,
{ alg: 'A128GCM',
kty: 'oct', ext: true
k: key, },
alg: 'A128GCM', {
ext: true name: 'AES-GCM'
}, },
{ true,
name: 'AES-GCM' ['encrypt', 'decrypt']
}, )
true, .then(cryptoKey => {
['encrypt', 'decrypt'] window.crypto.subtle
) .encrypt(
.then(cryptoKey => { {
window.crypto.subtle name: 'AES-GCM',
.encrypt( iv: hexToArray(IV),
{ tagLength: 128
name: 'AES-GCM', },
iv: hexToArray(IV), cryptoKey,
additionalData: hash, rawArray
tagLength: 128 )
}, .then(encrypted => {
cryptoKey, assert(
rawArray new Uint8Array(encrypted).toString() ===
) new Uint8Array(file).toString()
.then(encrypted => { );
assert( done();
new Uint8Array(encrypted).toString() === });
new Uint8Array(file).toString() });
);
done();
});
});
});
}; };
readRaw.readAsArrayBuffer(newFile); readRaw.readAsArrayBuffer(newFile);
@@ -179,7 +150,6 @@ describe('File Receiver', function() {
FakeXHR.prototype.getResponseHeader = function() { FakeXHR.prototype.getResponseHeader = function() {
return JSON.stringify({ return JSON.stringify({
aad: arrayToHex(new Uint8Array(fileHash)),
filename: 'hello_world.txt', filename: 'hello_world.txt',
id: encryptedIV id: encryptedIV
}); });
@@ -198,7 +168,6 @@ describe('File Receiver', function() {
if ( if (
file === undefined || file === undefined ||
encryptedIV === undefined || encryptedIV === undefined ||
fileHash === undefined ||
secretKey === undefined secretKey === undefined
) { ) {
assert.fail( assert.fail(
@@ -246,10 +215,6 @@ describe('File Receiver', function() {
testDecrypting = isStillDecrypting; testDecrypting = isStillDecrypting;
}); });
fr.on('safe', isSafe => {
assert(isSafe);
});
return fr return fr
.download() .download()
.then(([decrypted, name]) => { .then(([decrypted, name]) => {
@@ -262,123 +227,4 @@ describe('File Receiver', function() {
assert.fail(); assert.fail();
}); });
}); });
it('Should emit hashing events', function() {
const fr = new FileReceiver();
location.hash = secretKey;
let testHashing = true;
fr.on('hashing', isStillHashing => {
assert(!(!testHashing && isStillHashing));
testHashing = isStillHashing;
});
fr.on('safe', isSafe => {
assert(isSafe);
});
return fr
.download()
.then(([decrypted, name]) => {
assert(decrypted);
assert(name);
assert(!testHashing);
})
.catch(err => {
assert.fail();
});
});
it('Should catch fraudulent checksums', function(done) {
// Use the secret key and file hash of the previous file to encrypt,
// which has a different hash than this one (different strings).
const newFile = new FakeFile('hello_world.txt', [
'This is some data, with a changed hash.'
]);
const readRaw = new FileReader();
readRaw.onload = function(event) {
const plaintext = new Uint8Array(this.result);
window.crypto.subtle
.importKey(
'jwk',
{
kty: 'oct',
k: secretKey,
alg: 'A128GCM',
ext: true
},
{
name: 'AES-GCM'
},
true,
['encrypt', 'decrypt']
)
.then(key => {
// The file hash used here is the hash of the fake
// file from the previous test; it's a phony checksum.
return window.crypto.subtle.encrypt(
{
name: 'AES-GCM',
iv: hexToArray(encryptedIV),
additionalData: fileHash,
tagLength: 128
},
key,
plaintext
);
})
.then(encrypted => {
file = encrypted;
const fr = new FileReceiver();
location.hash = secretKey;
fr.on('unsafe', isUnsafe => {
assert(isUnsafe);
});
fr.on('safe', () => {
// This event should not be emitted.
assert.fail();
});
fr
.download()
.then(() => {
assert.fail();
done();
})
.catch(err => {
assert(1);
done();
});
});
};
readRaw.readAsArrayBuffer(newFile);
});
it('Should not decrypt with an incorrect checksum', function() {
FakeXHR.prototype.getResponseHeader = function() {
return JSON.stringify({
aad: 'some_bad_hashz',
filename: 'hello_world.txt',
id: encryptedIV
});
};
const fr = new FileReceiver();
location.hash = secretKey;
return fr
.download()
.then(([decrypted, name]) => {
assert(decrypted);
assert(name);
assert.fail();
})
.catch(err => {
assert(1);
});
});
}); });

View File

@@ -46,7 +46,6 @@ describe('Server integration tests', function() {
.set( .set(
'X-File-Metadata', 'X-File-Metadata',
JSON.stringify({ JSON.stringify({
aad: '11111',
id: '111111111111111111111111', id: '111111111111111111111111',
filename: 'test_upload.txt' filename: 'test_upload.txt'
}) })
@@ -164,7 +163,7 @@ describe('Server integration tests', function() {
res.header['content-disposition'], res.header['content-disposition'],
'attachment; filename=test_upload.txt' 'attachment; filename=test_upload.txt'
); );
assert.equal(res.header['content-type'], 'application/octet-stream'); assert.equal(res.header['content-type'], 'text/plain');
}); });
}); });

View File

@@ -1,39 +0,0 @@
<div id="download">
<script src="/download.js"></script>
<div id="download-page-one">
<div class="title">
<span id="dl-filename"
data-l10n-id="downloadFileName"
data-l10n-args='{"filename": "{{filename}}"}'></span>
<span data-l10n-id="downloadFileSize"
data-l10n-args='{"size": "{{filesize}}"}'></span>
<span id="dl-bytelength" hidden="true">{{sizeInBytes}}</span>
<span id="dl-ttl" hidden="true">{{timeToExpiry}}</span>
</div>
<div class="description" data-l10n-id="downloadMessage"></div>
<img src="/resources/illustration_download.svg" id="download-img" data-l10n-id="downloadAltText"/>
<div>
<button id="download-btn" data-l10n-id="downloadButtonLabel"></button>
</div>
</div>
<div id="download-progress" hidden="true">
<div class="title"
data-l10n-id="downloadingPageProgress"
data-l10n-args='{"filename": "{{filename}}", "size": "{{filesize}}"}'>
</div>
<div class="description" data-l10n-id="downloadingPageMessage"></div>
<!-- progress bar here -->
<div class="progress-bar" id="dl-progress">
<div class="percentage">
<span class="percent-number"></span>
<span class="percent-sign">%</span>
</div>
</div>
<div class="upload">
<div class="progress-text">{{filename}}</div>
</div>
</div>
<a class="send-new" data-l10n-id="sendYourFilesLink" target="_blank"></a>
</div>

View File

@@ -1,59 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="defaultLanguage" content="en-US">
<meta name="availableLanguages" content="{{availableLanguages}}">
<title>Firefox Send</title>
<link rel="stylesheet" type="text/css" href="/main.css" />
{{#if fira}}
<link rel="stylesheet" type="text/css" href="https://code.cdn.mozilla.net/fonts/fira.css" />
{{/if}}
<link rel="icon" type="image/png" href="/resources/favicon-32x32.png" sizes="32x32" />
<link rel="localization" href="/locales/{locale}/send.ftl">
<script src="/jsconfig.js"></script>
<script src="/polyfill.min.js"></script>
<script defer src="/l20n.min.js"></script>
</head>
<body>
<header class="header">
<div class="send-logo">
<a href="/">
<img src="/resources/send_logo.svg" alt="Send"/><h1 class="site-title">Send</h1>
</a>
<div class="site-subtitle">
<a href="https://testpilot.firefox.com" target="_blank">Firefox Test Pilot</a>
<div data-l10n-id="siteSubtitle">web experiment</div>
</div>
</div>
<a href="https://qsurvey.mozilla.com/s3/txp-firefox-send" rel="noreferrer noopener" class="feedback" target="_blank" data-l10n-id="siteFeedback">Feedback</a>
</header>
<div class="all">
<noscript>
<h2>Firefox Send requires JavaScript</h2>
<p><a href="https://github.com/mozilla/send/blob/master/docs/faq.md#why-does-firefox-send-require-javascript" target="_blank" rel="noreferrer noopener">Why does Firefox Send require JavaScript?</a></p>
<p>Please enable JavaScript and try again.</p>
</noscript>
{{{body}}}
</div>
<div class="footer">
<div class="legal-links">
<a href="https://www.mozilla.org" target="_blank"><img class="mozilla-logo" src="/resources/mozilla-logo.svg"/></a>
<a href="https://www.mozilla.org/about/legal" data-l10n-id="footerLinkLegal" target="_blank">Legal</a>
<a href="https://testpilot.firefox.com/about" data-l10n-id="footerLinkAbout" target="_blank">About Test Pilot</a>
<a href="/legal" data-l10n-id="footerLinkPrivacy" target="_blank">Privacy</a>
<a href="/legal" data-l10n-id="footerLinkTerms" target="_blank">Terms</a>
<a href="https://www.mozilla.org/privacy/websites/#cookies" data-l10n-id="footerLinkCookies" target="_blank">Cookies</a>
</div>
<div class="social-links">
<a href="https://github.com/mozilla/send" target="_blank" rel="noreferrer noopener"><img class="github" src="/resources/github-icon.svg"/></a>
<a href="https://twitter.com/FxTestPilot" target="_blank" rel="noreferrer noopener"><img class="twitter" src="/resources/twitter-icon.svg"/></a>
</div>
</div>
</body>
</html>

124
webpack.config.js Normal file
View File

@@ -0,0 +1,124 @@
const path = require('path');
const webpack = require('webpack');
const HtmlPlugin = require('html-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
entry: {
vendor: ['babel-polyfill', 'raven-js'],
upload: ['./frontend/src/upload.js'],
download: ['./frontend/src/download.js']
},
output: {
filename: 'resources/[name].[chunkhash].js',
path: path.resolve(__dirname, 'dist/public'),
publicPath: '/'
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
include: [
path.resolve(__dirname, 'frontend'),
path.resolve(__dirname, 'node_modules/testpilot-ga/src')
],
options: {
babelrc: false,
presets: [['es2015', { modules: false }], 'stage-2']
}
},
{
test: /\.(svg|png|jpg)$/,
loader: 'file-loader',
options: {
name: 'resources/[name].[hash].[ext]'
}
},
{
test: /\.css$/,
use: [
{
loader: 'file-loader',
options: {
name: 'resources/[name].[hash].[ext]'
}
},
'extract-loader',
{ loader: 'css-loader', options: { importLoaders: 1 } },
'postcss-loader'
]
},
{
test: /\.hbs$/,
use: [
{
loader: 'html-loader',
options: {
interpolate: 'require',
minimize: false
}
}
]
}
]
},
plugins: [
new CopyPlugin([
{
context: 'public',
from: 'locales/**/*.ftl'
},
{
context: 'public',
from: '*.*'
},
{
from: 'views/**',
to: '../'
},
{
context: 'node_modules/l20n/dist/web',
from: 'l20n.min.js'
}
]),
new HtmlPlugin({
filename: '../views/index.handlebars',
template: 'webpack/upload.hbs',
chunks: ['upload']
}),
new HtmlPlugin({
filename: '../views/download.handlebars',
template: 'webpack/download.hbs',
chunks: ['download']
}),
new HtmlPlugin({
filename: '../views/legal.handlebars',
template: 'webpack/legal.hbs',
inject: false
}),
new HtmlPlugin({
filename: '../views/notfound.handlebars',
template: 'webpack/notfound.hbs',
inject: false
}),
new HtmlPlugin({
filename: '../views/layouts/main.handlebars',
template: 'webpack/layout.hbs',
inject: 'head',
excludeChunks: ['upload', 'download']
}),
new HtmlPlugin({
filename: '../views/unsupported.handlebars',
template: 'webpack/unsupported.hbs',
inject: false
}),
new webpack.HashedModuleIdsPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor'
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'runtime'
})
]
};

43
webpack/download.hbs Normal file
View File

@@ -0,0 +1,43 @@
<div id="download">
<div id="download-page-one">
<div class="title">
<span id="dl-file"
data-filename="{{filename}}"
data-size="{{sizeInBytes}}"
data-ttl="{{ttl}}"
data-l10n-id="downloadFileName"
data-l10n-args='{{filenameJson}}'></span>
<span id="dl-filesize"></span>
</div>
<div class="description" data-l10n-id="downloadMessage"></div>
<img src="../public/resources/illustration_download.svg" id="download-img" data-l10n-id="downloadAltText"/>
<div>
<button id="download-btn" class="btn" data-l10n-id="downloadButtonLabel"></button>
</div>
</div>
<div id="download-progress" hidden="true">
<div id="dl-title" class="title"></div>
<div class="description" data-l10n-id="downloadingPageMessage"></div>
<div class="progress-bar">
<svg id="progress" width="166" height="166" viewPort="0 0 166 166" version="1.1">
<circle r="73" cx="83" cy="83" fill="transparent"/>
<circle id="bar" r="73" cx="83" cy="83" fill="transparent" transform="rotate(-90 83 83)" stroke-dasharray="458.67" stroke-dashoffset="458.67"/>
</svg>
<div class="percentage">
<span class="percent-number"></span>
<span class="percent-sign">%</span>
</div>
</div>
<div class="upload">
<div class="progress-text">{{filename}}</div>
</div>
</div>
<div id="upload-error" hidden="true">
<div class="title" data-l10n-id="errorPageHeader"></div>
<img id="upload-error-img" data-l10n-id="errorAltText" src="../public/resources/illustration_error.svg"/>
</div>
<a class="send-new" data-state="completed" data-l10n-id="sendYourFilesLink" href="/"></a>
</div>

69
webpack/layout.hbs Normal file
View File

@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="defaultLanguage" content="en-US">
<meta name="availableLanguages" content="{{availableLanguages}}">
<meta property="og:title" content="{{title}}"/>
<meta name="twitter:title" content="{{title}}"/>
<meta name="description" content="{{description}}"/>
<meta property="og:description" content="{{description}}"/>
<meta name="twitter:description" content="{{description}}"/>
<meta name="twitter:card" content="summary"/>
<meta property="og:image" content="{{baseUrl}}${require('../public/resources/send-fb.jpg')}"/>
<meta name="twitter:image" content="{{baseUrl}}${require('../public/resources/send-twitter.jpg')}"/>
<meta property="og:url" content="{{baseUrl}}"/>
<title>{{title}}</title>
<link rel="stylesheet" type="text/css" href="${require('../frontend/src/main.css')}" />
{{#if fira}}
<link rel="stylesheet" type="text/css" href="https://code.cdn.mozilla.net/fonts/fira.css" />
{{/if}}
<link rel="icon" type="image/png" href="${require('../public/resources/favicon-32x32.png')}" sizes="32x32" />
<link rel="localization" href="/locales/{locale}/send.ftl">
<script src="/jsconfig.js"></script>
<script defer src="/l20n.min.js"></script>
</head>
<body>
<header class="header">
<div class="send-logo">
<a href="/">
<img src="../public/resources/send_logo.svg" alt="Send"/><h1 class="site-title">Send</h1>
</a>
<div class="site-subtitle">
<a href="https://testpilot.firefox.com">Firefox Test Pilot</a>
<div data-l10n-id="siteSubtitle">web experiment</div>
</div>
</div>
<a href="https://qsurvey.mozilla.com/s3/txp-firefox-send" rel="noreferrer noopener" class="feedback" target="_blank" data-l10n-id="siteFeedback">Feedback</a>
</header>
<div class="all">
<noscript>
<h2>Firefox Send requires JavaScript</h2>
<p><a href="https://github.com/mozilla/send/blob/master/docs/faq.md#why-does-firefox-send-require-javascript">Why does Firefox Send require JavaScript?</a></p>
<p>Please enable JavaScript and try again.</p>
</noscript>
{{{body}}}
</div>
<div class="footer">
<div class="legal-links">
<a href="https://www.mozilla.org" role="presentation"><img class="mozilla-logo" src="../public/resources/mozilla-logo.svg" alt="mozilla"/></a>
<a href="https://www.mozilla.org/about/legal" data-l10n-id="footerLinkLegal">Legal</a>
<a href="https://testpilot.firefox.com/about" data-l10n-id="footerLinkAbout">About Test Pilot</a>
<a href="/legal" data-l10n-id="footerLinkPrivacy">Privacy</a>
<a href="/legal" data-l10n-id="footerLinkTerms">Terms</a>
<a href="https://www.mozilla.org/privacy/websites/#cookies" data-l10n-id="footerLinkCookies">Cookies</a>
</div>
<div class="social-links">
<a href="https://github.com/mozilla/send" role="presentation"><img class="github" src="../public/resources/github-icon.svg" alt="github"/></a>
<a href="https://twitter.com/FxTestPilot" role="presentation"><img class="twitter" src="../public/resources/twitter-icon.svg" alt="twitter"/></a>
</div>
</div>
</body>
</html>

View File

@@ -1,8 +1,8 @@
<div id="download"> <div id="download">
<div class="title" data-l10n-id="expiredPageHeader"></div> <div class="title" data-l10n-id="expiredPageHeader"></div>
<div class="share-window"> <div class="share-window">
<img src="/resources/illustration_expired.svg" id="expired-img" data-l10n-id="linkExpiredAlt"/> <img src="../public/resources/illustration_expired.svg" id="expired-img" data-l10n-id="linkExpiredAlt"/>
</div> </div>
<div class="expired-description" data-l10n-id="uploadPageExplainer"></div> <div class="expired-description" data-l10n-id="uploadPageExplainer"></div>
<a class="send-new" href="/" id="expired-send-new" data-l10n-id="sendYourFilesLink"></a> <a class="send-new" href="/" data-state="notfound" data-l10n-id="sendYourFilesLink"></a>
</div> </div>

View File

@@ -3,14 +3,14 @@
{{#if outdated}} {{#if outdated}}
<div class="description" data-l10n-id="notSupportedOutdatedDetail">Unfortunately this version of Firefox does not support the web technology that powers Firefox Send. Youll need to update your browser.</div> <div class="description" data-l10n-id="notSupportedOutdatedDetail">Unfortunately this version of Firefox does not support the web technology that powers Firefox Send. Youll need to update your browser.</div>
<a id="update-firefox" href="https://support.mozilla.org/kb/update-firefox-latest-version"> <a id="update-firefox" href="https://support.mozilla.org/kb/update-firefox-latest-version">
<img src="/resources/firefox_logo-only.svg" class="firefox-logo" alt="Firefox"/> <img src="../public/resources/firefox_logo-only.svg" class="firefox-logo" alt="Firefox"/>
<div class="unsupported-button-text" data-l10n-id="updateFirefox">Update Firefox</div> <div class="unsupported-button-text" data-l10n-id="updateFirefox">Update Firefox</div>
</a> </a>
{{else}} {{else}}
<div class="description" data-l10n-id="notSupportedDetail">Unfortunately this browser does not support the web technology that powers Firefox Send. Youll need to try another browser. We recommend Firefox!</div> <div class="description" data-l10n-id="notSupportedDetail">Unfortunately this browser does not support the web technology that powers Firefox Send. Youll need to try another browser. We recommend Firefox!</div>
<div class="description"><a href="https://github.com/mozilla/send/blob/master/docs/faq.md#why-is-my-browser-not-supported" data-l10n-id="notSupportedLink" target="_blank" rel="noopener noreferrer">Why is my browser not supported?</a></div> <div class="description"><a href="https://github.com/mozilla/send/blob/master/docs/faq.md#why-is-my-browser-not-supported" data-l10n-id="notSupportedLink">Why is my browser not supported?</a></div>
<a id="dl-firefox" href="https://www.mozilla.org/firefox/new/?scene=2" target="_blank"> <a id="dl-firefox" href="https://www.mozilla.org/firefox/new/?scene=2">
<img src="/resources/firefox_logo-only.svg" class="firefox-logo" alt="Firefox"/> <img src="../public/resources/firefox_logo-only.svg" class="firefox-logo" alt="Firefox"/>
<div class="unsupported-button-text">Firefox<br> <div class="unsupported-button-text">Firefox<br>
<span data-l10n-id="downloadFirefoxButtonSub">Free Download</span> <span data-l10n-id="downloadFirefoxButtonSub">Free Download</span>
</div> </div>

View File

@@ -1,17 +1,16 @@
<div id="page-one" hidden> <div id="page-one" hidden>
<script src="/upload.js"></script>
<div class="title" data-l10n-id="uploadPageHeader"></div> <div class="title" data-l10n-id="uploadPageHeader"></div>
<div class="description"> <div class="description">
<div data-l10n-id="uploadPageExplainer"></div> <div data-l10n-id="uploadPageExplainer"></div>
<a href="https://testpilot.firefox.com/experiments/send" class="link" data-l10n-id="uploadPageLearnMore"></a> <a href="https://testpilot.firefox.com/experiments/send" class="link" data-l10n-id="uploadPageLearnMore"></a>
</div> </div>
<div class="upload-window" > <div class="upload-window" >
<div id="upload-img"><img data-l10n-id="uploadSvgAlt" src="/resources/upload.svg"/></div> <div id="upload-img"><img data-l10n-id="uploadSvgAlt" src="../public/resources/upload.svg"/></div>
<div id="upload-text" data-l10n-id="uploadPageDropMessage"></div> <div id="upload-text" data-l10n-id="uploadPageDropMessage"></div>
<span id="file-size-msg"><em data-l10n-id="uploadPageSizeMessage"></em></span> <span id="file-size-msg"><em data-l10n-id="uploadPageSizeMessage"></em></span>
<form method="post" action="upload" enctype="multipart/form-data"> <form method="post" action="upload" enctype="multipart/form-data">
<label for="file-upload" id="browse" <label for="file-upload" id="browse"
data-l10n-id="uploadPageBrowseButton"></label> data-l10n-id="uploadPageBrowseButton1" class="btn"></label>
<input id="file-upload" type="file" name="fileUploaded" /> <input id="file-upload" type="file" name="fileUploaded" />
</form> </form>
</div> </div>
@@ -21,10 +20,10 @@
<thead> <thead>
<tr> <tr>
<!-- htmllint attr-bans="false" --> <!-- htmllint attr-bans="false" -->
<th width="35%" data-l10n-id="uploadedFile"></th> <th id="uploaded-file" data-l10n-id="uploadedFile"></th>
<th width="25%" data-l10n-id="copyFileList"></th> <th id="copy-file-list" data-l10n-id="copyFileList"></th>
<th width="21%" data-l10n-id="expiryFileList"></th> <th id="expiry-file-list" data-l10n-id="expiryFileList"></th>
<th width="12%" data-l10n-id="deleteFileList"></th> <th id="delete-file-list" data-l10n-id="deleteFileList"></th>
<!-- htmllint tag-bans="$previous" --> <!-- htmllint tag-bans="$previous" -->
</tr> </tr>
</thead> </thead>
@@ -35,10 +34,13 @@
</div> </div>
<div id="upload-progress" hidden="true"> <div id="upload-progress" hidden="true">
<div class="title" id="upload-filename" data-l10n-id="uploadingPageHeader"></div> <div class="title" id="upload-filename"></div>
<div class="description"></div> <div class="description"></div>
<!-- progress bar here --> <div class="progress-bar">
<div class="progress-bar" id="ul-progress"> <svg id="progress" width="166" height="166" viewPort="0 0 166 166" version="1.1">
<circle r="73" cx="83" cy="83" fill="transparent"/>
<circle id="bar" r="73" cx="83" cy="83" fill="transparent" transform="rotate(-90 83 83)" stroke-dasharray="458.67" stroke-dashoffset="458.67"/>
</svg>
<div class="percentage"> <div class="percentage">
<span class="percent-number">0</span> <span class="percent-number">0</span>
<span class="percent-sign">%</span> <span class="percent-sign">%</span>
@@ -58,16 +60,16 @@
<div id="copy-text"></div> <div id="copy-text"></div>
<div id="copy"> <div id="copy">
<input id="link" type="url" value="" readonly/> <input id="link" type="url" value="" readonly/>
<button id="copy-btn" data-l10n-id="copyUrlFormButton"></button> <button id="copy-btn" class="btn" data-l10n-id="copyUrlFormButton"></button>
</div> </div>
<button id="delete-file" data-l10n-id="deleteFileButton"></button> <button id="delete-file" class="btn" data-l10n-id="deleteFileButton"></button>
<a class="send-new" id="send-new-completed" data-l10n-id="sendAnotherFileLink"></a> <a class="send-new" data-state="completed" data-l10n-id="sendAnotherFileLink" href="/"></a>
</div> </div>
</div> </div>
<div id="upload-error" hidden="true"> <div id="upload-error" hidden="true">
<div class="title" data-l10n-id="errorPageHeader"></div> <div class="title" data-l10n-id="errorPageHeader"></div>
<div class="expired-description" data-l10n-id="errorPageMessage"></div> <div class="expired-description" data-l10n-id="errorPageMessage"></div>
<img id="upload-error-img" data-l10n-id="errorAltText" src="/resources/illustration_error.svg"/> <img id="upload-error-img" data-l10n-id="errorAltText" src="../public/resources/illustration_error.svg"/>
<a class="send-new" id="send-new-error" data-l10n-id="sendAnotherFileLink"></a> <a class="send-new" href="/" data-state="errored" data-l10n-id="sendAnotherFileLink"></a>
</div> </div>