mirror of
https://gitlab.com/timvisee/send.git
synced 2025-12-07 14:40:55 +03:00
Compare commits
112 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94f1eabbc7 | ||
|
|
902bc6628e | ||
|
|
460b741f17 | ||
|
|
d5c488196d | ||
|
|
9ad9c9feb2 | ||
|
|
6576e4a74c | ||
|
|
950872109e | ||
|
|
87051d27ed | ||
|
|
3451803b37 | ||
|
|
ac15153e8f | ||
|
|
924f5dc682 | ||
|
|
ff9be6a213 | ||
|
|
883728570e | ||
|
|
0435f17f9a | ||
|
|
1e1268fff0 | ||
|
|
252d7817e3 | ||
|
|
ce28c38ebe | ||
|
|
f0407f9beb | ||
|
|
c6f222eb57 | ||
|
|
6dd6135185 | ||
|
|
8df339b66d | ||
|
|
8702fda651 | ||
|
|
807ecff471 | ||
|
|
927c981cd7 | ||
|
|
7073cc8ce6 | ||
|
|
c925fae696 | ||
|
|
966d7a5e35 | ||
|
|
96c750c098 | ||
|
|
0729064753 | ||
|
|
259a5a5f24 | ||
|
|
27be72e0cd | ||
|
|
e4231bbc0f | ||
|
|
1d184f06bf | ||
|
|
f7b46a99ac | ||
|
|
3fadb489c7 | ||
|
|
6378676c2d | ||
|
|
014d84e4c7 | ||
|
|
a08d8435a9 | ||
|
|
40a05c9ecf | ||
|
|
527040afef | ||
|
|
a48a447808 | ||
|
|
f3569d7f98 | ||
|
|
6ca7d11efb | ||
|
|
b71ae4a0ff | ||
|
|
7ba25664b5 | ||
|
|
80fb42ad3d | ||
|
|
f036df5f47 | ||
|
|
20c063db7c | ||
|
|
a6b43c9eef | ||
|
|
c80f9ada65 | ||
|
|
e0ae5cb3c6 | ||
|
|
c0fb3d17be | ||
|
|
116f090b7e | ||
|
|
7cbd9716e2 | ||
|
|
58191975b9 | ||
|
|
76695aee5d | ||
|
|
b356b4cad3 | ||
|
|
63ddbeefc4 | ||
|
|
7b423b24b6 | ||
|
|
b67050b742 | ||
|
|
06242dfd38 | ||
|
|
3b8dbfd81c | ||
|
|
9c2fe39764 | ||
|
|
8b21d43bfa | ||
|
|
e7e39f4d4a | ||
|
|
e4c801d9a1 | ||
|
|
324f275dd4 | ||
|
|
594e0bd28e | ||
|
|
6a7fdfe780 | ||
|
|
0c82741b98 | ||
|
|
fe57734792 | ||
|
|
4754bed9b8 | ||
|
|
a60da467b9 | ||
|
|
362da2bbfc | ||
|
|
1a9ef4a246 | ||
|
|
f51dbbb8f5 | ||
|
|
e497107e59 | ||
|
|
10ad6fc1ae | ||
|
|
c982db4c75 | ||
|
|
cd8130563d | ||
|
|
730a569d43 | ||
|
|
769dae1bdc | ||
|
|
54a8c504ce | ||
|
|
92dc9a0f71 | ||
|
|
80a7c92056 | ||
|
|
c6ebea0100 | ||
|
|
039b5daaed | ||
|
|
4bf4e61c2c | ||
|
|
3c21e2a00f | ||
|
|
38a379d1de | ||
|
|
adeb19d974 | ||
|
|
744c410704 | ||
|
|
99ab3882eb | ||
|
|
7cdf566bcd | ||
|
|
b6e4877d93 | ||
|
|
b9c87fd779 | ||
|
|
6ef5b5133c | ||
|
|
b7d2420765 | ||
|
|
c139531c91 | ||
|
|
88fe3902bc | ||
|
|
645fd062ac | ||
|
|
ccb0b71df5 | ||
|
|
b8ec90a398 | ||
|
|
7ed5f37c66 | ||
|
|
c899129f9a | ||
|
|
1bb91690c5 | ||
|
|
073f6f67d3 | ||
|
|
533bfdb496 | ||
|
|
34de65d7d2 | ||
|
|
209fdf34f8 | ||
|
|
ba5c2a049d | ||
|
|
1528aa3f1b |
@@ -2,5 +2,6 @@ dist
|
||||
assets
|
||||
firefox
|
||||
coverage
|
||||
android/app/build
|
||||
app/locale.js
|
||||
app/capabilities.js
|
||||
@@ -4,6 +4,7 @@ env:
|
||||
|
||||
extends:
|
||||
- eslint:recommended
|
||||
- prettier
|
||||
- plugin:node/recommended
|
||||
- plugin:security/recommended
|
||||
|
||||
@@ -22,13 +23,5 @@ rules:
|
||||
security/detect-non-literal-fs-filename: off
|
||||
security/detect-object-injection: off
|
||||
|
||||
eol-last: [error, always]
|
||||
eqeqeq: error
|
||||
no-alert: warn
|
||||
no-console: warn
|
||||
no-path-concat: error
|
||||
no-unused-vars: [error, {argsIgnorePattern: "^_|err|event|next|reject"}]
|
||||
no-var: error
|
||||
one-var: [error, never]
|
||||
prefer-const: error
|
||||
quotes: [error, single, {avoidEscape: true}]
|
||||
require-atomic-updates: warn
|
||||
|
||||
41
CONTRIBUTORS
41
CONTRIBUTORS
@@ -4,15 +4,18 @@ Adnan Kičin
|
||||
Alberto Castro
|
||||
Alexander Slovesnik
|
||||
Alfredos-Panagiotis Damkalis
|
||||
Aman Alam
|
||||
Amin Mahmudian
|
||||
Ander Elortondo
|
||||
Andreas Pettersson
|
||||
Anesu Chiodza
|
||||
Anika Dorn
|
||||
Anish Sheela
|
||||
Arash Mousavi
|
||||
Artem Polivanchuk
|
||||
Ashikur Rahman
|
||||
Ashok kumar
|
||||
Balasankar C
|
||||
Balázs Meskó
|
||||
Belayet Hossain
|
||||
Benjamin Forehand Jr
|
||||
@@ -20,8 +23,11 @@ Besnik Bleta
|
||||
Björn I
|
||||
Bjørn I
|
||||
Boopesh Mahendran
|
||||
Brahim Essaidi
|
||||
Brainlulz
|
||||
Breana Gonzales
|
||||
Christian Elbrianno
|
||||
Christoph Kührer
|
||||
Christopher Ramírez
|
||||
Chuck Harmston
|
||||
Cloney 173741
|
||||
@@ -31,6 +37,7 @@ Cynthia Pereira
|
||||
Daniel Thorn
|
||||
Daniela Arcese
|
||||
Danny Coates
|
||||
Davide
|
||||
Derek Tamsen
|
||||
Dhyey Thakore
|
||||
Donovan Preston
|
||||
@@ -52,11 +59,16 @@ Frederick Villaluna
|
||||
G12r
|
||||
Gabriela
|
||||
Gautam krishna.R
|
||||
George Raptis
|
||||
Georgianizator
|
||||
Gonçalo Matos
|
||||
Gwenn
|
||||
Hugo
|
||||
Hugo Abreu
|
||||
Hyeonseok Shin
|
||||
Håvar Henriksen
|
||||
Ian Neal
|
||||
ItielMaN
|
||||
Jae Hyeon Park
|
||||
Jakob Kappel
|
||||
Jakub Rychlý
|
||||
@@ -65,6 +77,8 @@ Jarmo
|
||||
Jim Spentzos
|
||||
Jiri Grönroos
|
||||
Jobava
|
||||
Joe Becher
|
||||
Joe ST
|
||||
Joergen
|
||||
Johann-S
|
||||
John Gruen
|
||||
@@ -81,9 +95,11 @@ Khaled Hosny
|
||||
Kim Ludvigsen
|
||||
Kohei Yoshino
|
||||
Lan Glad
|
||||
Lasse Liehu
|
||||
Laurent Jouanneau
|
||||
Lobodzets
|
||||
LuFlo
|
||||
Luis A. Sánchez
|
||||
Luiz Carlos de Morais
|
||||
Luna Jernberg
|
||||
Mahay Alam Khan
|
||||
@@ -106,14 +122,18 @@ Michal Vašíček
|
||||
Mikeyy
|
||||
Miro Rauhala
|
||||
Mozilla Pontoon
|
||||
Mozilla-GitHub-Standards
|
||||
Mozinet
|
||||
Moḥend Belqasem
|
||||
Muhend Belkacem
|
||||
Muḥend Belqasem
|
||||
Myungjae Won
|
||||
Nicholas Skinsacos
|
||||
Nihad
|
||||
Nihad Suljić
|
||||
Oscar
|
||||
Paulius
|
||||
Pedro Burlamaqui Bendahan
|
||||
Peter deHaan
|
||||
Pierre Neter
|
||||
Pin-guang Chen
|
||||
@@ -125,10 +145,12 @@ RickieES
|
||||
Rimas Kudelis
|
||||
Rizky Ariestiyansyah
|
||||
Rob Powell
|
||||
Robert
|
||||
Roberto Alvarado
|
||||
Rodrigo
|
||||
Rodrigo Guerra
|
||||
Rok Žerdin
|
||||
Romi Hardiyanto
|
||||
Rongjian Zhang
|
||||
Ruba
|
||||
Sahithi
|
||||
@@ -139,9 +161,12 @@ Sara Todaro
|
||||
Sav22999
|
||||
Schieck :)
|
||||
Selim Şumlu
|
||||
Sidak Singh Aulakh
|
||||
Slimane Amiri
|
||||
Slimane Selyan AMIRI
|
||||
Soumya Himanish Mohapatra
|
||||
Staś Małolepszy
|
||||
Suriyaa ✌️️
|
||||
Tema
|
||||
Thomas Dalichow
|
||||
Théo Chevalier
|
||||
@@ -150,6 +175,7 @@ Tim Visée
|
||||
Tomer Cohen
|
||||
Tomáš Zelina
|
||||
Ton
|
||||
Top
|
||||
Tymur Faradzhev
|
||||
Uccen Marzuq
|
||||
Varghese Thomas
|
||||
@@ -159,6 +185,7 @@ Vitaliy Krutko
|
||||
Weihang Lo
|
||||
Wil Clouser
|
||||
YFdyh000
|
||||
Yassine Aït-El-Mouden
|
||||
Yongmin H
|
||||
You-Wen Liang (Mark)
|
||||
aaaaalbert
|
||||
@@ -169,6 +196,7 @@ alex_mayorga
|
||||
ariestiyansyah
|
||||
avelper
|
||||
chilledfrogs
|
||||
clouserw-mozilla-owner
|
||||
dgadelha
|
||||
dskmori
|
||||
ehuggett
|
||||
@@ -180,25 +208,35 @@ gmontagu
|
||||
goofy
|
||||
hello
|
||||
hi
|
||||
ivan.pompa
|
||||
jesferman1993
|
||||
jlG
|
||||
josotrix
|
||||
jspam
|
||||
julenx
|
||||
kenrick95
|
||||
kumincir
|
||||
m4hdi.pdroid
|
||||
mail
|
||||
manxmensch
|
||||
marigalicer
|
||||
marsf
|
||||
merianosnikos
|
||||
mirzet.omerovic.1992
|
||||
mujeebcpy
|
||||
p.sanroman.bengoetxea
|
||||
passionforlife
|
||||
paul.trevor
|
||||
pyup.io bot
|
||||
ravmn
|
||||
rcmainak
|
||||
reza.habibi2008
|
||||
rgpublic
|
||||
risger
|
||||
robbp
|
||||
ruikunai
|
||||
savemore99.sm
|
||||
sergio
|
||||
shikhar-scs
|
||||
siparon
|
||||
skystar-p
|
||||
@@ -210,10 +248,13 @@ victor.gonzalezro
|
||||
xcffl
|
||||
ybouhamam
|
||||
yoshimitsu002
|
||||
yusup.ramdani
|
||||
Μιχάλης
|
||||
Марко Костић (Marko Kostić)
|
||||
Ратко Вујановић
|
||||
صفا الفليج
|
||||
వీవెన్
|
||||
ജോയ്സ്
|
||||
张无忌
|
||||
新垣结衣松冈茉优长泽雅美门胁麦上野树里石原里美
|
||||
莫非前世那一眼
|
||||
|
||||
@@ -10,6 +10,7 @@ USER app
|
||||
WORKDIR /app
|
||||
COPY --chown=app:app --from=builder /app .
|
||||
COPY --chown=app:app . .
|
||||
RUN mkdir -p /app/.config/configstore
|
||||
RUN ln -s dist/version.json version.json
|
||||
|
||||
ENV PORT=1443
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
* [Localization](#localization)
|
||||
* [Contributing](#contributing)
|
||||
* [Testing](#testing)
|
||||
* [Deployment](#deployment)
|
||||
* [Android](#android)
|
||||
* [License](#license)
|
||||
|
||||
@@ -91,6 +92,12 @@ Pull requests are always welcome! Feel free to check out the list of ["good firs
|
||||
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
see also [docs/deployment.md](docs/deployment.md)
|
||||
|
||||
---
|
||||
|
||||
## Android
|
||||
|
||||
The android implementation is contained in the `android` directory, and can be viewed locally for easy testing and editing by running `ANDROID=1 npm start` and then visiting <http://localhost:8080>. CSS and image files are located in the `android/app/src/main/assets` directory.
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/* global window, navigator */
|
||||
import 'fluent-intl-polyfill';
|
||||
import 'intl-pluralrules';
|
||||
import choo from 'choo';
|
||||
import html from 'choo/html';
|
||||
import Raven from 'raven-js';
|
||||
import * as Sentry from '@sentry/browser';
|
||||
|
||||
import { setApiUrlPrefix, getConstants } from '../app/api';
|
||||
import metrics from '../app/metrics';
|
||||
@@ -53,7 +52,7 @@ function body(main) {
|
||||
|
||||
const menu = html`<a
|
||||
id="hamburger"
|
||||
class="absolute pin-t pin-r z-50"
|
||||
class="absolute top-0 right-0 z-50"
|
||||
href="#"
|
||||
onclick="${clickPreferences}"
|
||||
>
|
||||
@@ -83,7 +82,7 @@ function body(main) {
|
||||
state.archive = new Archive([], DEFAULTS.EXPIRE_SECONDS);
|
||||
state.storage = storage;
|
||||
state.user = new User(storage, LIMITS);
|
||||
state.raven = Raven;
|
||||
state.sentry = Sentry;
|
||||
});
|
||||
app.use(metrics);
|
||||
app.route('/', body(home));
|
||||
|
||||
@@ -42,11 +42,7 @@ module.exports = function(state, emit) {
|
||||
content =
|
||||
archives.length < 1
|
||||
? intro(state)
|
||||
: list(
|
||||
archives,
|
||||
'list-reset h-full overflow-y-auto w-full',
|
||||
'mb-3 w-full'
|
||||
);
|
||||
: list(archives, 'h-full overflow-y-auto w-full', 'mb-3 w-full');
|
||||
}
|
||||
|
||||
return html`
|
||||
@@ -57,7 +53,7 @@ module.exports = function(state, emit) {
|
||||
>
|
||||
${content}
|
||||
</section>
|
||||
<div class="fixed pin-r pin-b z-20">
|
||||
<div class="fixed right-0 bottom-0 z-20">
|
||||
${button}
|
||||
<input
|
||||
id="file-upload"
|
||||
|
||||
@@ -12,7 +12,7 @@ export default function initialState(state, emitter) {
|
||||
getAsset(name) {
|
||||
return `${state.prefix}/${name}`;
|
||||
},
|
||||
raven: {
|
||||
sentry: {
|
||||
captureException: e => {
|
||||
console.error('ERROR ' + e + ' ' + e.stack);
|
||||
}
|
||||
|
||||
78
app/api.js
78
app/api.js
@@ -11,6 +11,15 @@ if (!fileProtocolWssUrl) {
|
||||
fileProtocolWssUrl = 'wss://send.firefox.com/api/ws';
|
||||
}
|
||||
|
||||
export class ConnectionError extends Error {
|
||||
constructor(cancelled, duration, size) {
|
||||
super(cancelled ? '0' : 'connection closed');
|
||||
this.cancelled = cancelled;
|
||||
this.duration = duration;
|
||||
this.size = size;
|
||||
}
|
||||
}
|
||||
|
||||
export function setFileProtocolWssUrl(url) {
|
||||
localStorage && localStorage.setItem('wssURL', url);
|
||||
fileProtocolWssUrl = url;
|
||||
@@ -137,17 +146,25 @@ export async function setPassword(id, owner_token, keychain) {
|
||||
}
|
||||
|
||||
function asyncInitWebSocket(server) {
|
||||
return new Promise(resolve => {
|
||||
const ws = new WebSocket(server);
|
||||
ws.onopen = () => {
|
||||
resolve(ws);
|
||||
};
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const ws = new WebSocket(server);
|
||||
ws.addEventListener('open', () => resolve(ws), { once: true });
|
||||
} catch (e) {
|
||||
reject(new ConnectionError(false));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function listenForResponse(ws, canceller) {
|
||||
return new Promise((resolve, reject) => {
|
||||
function handleClose(event) {
|
||||
// a 'close' event before a 'message' event means the request failed
|
||||
ws.removeEventListener('message', handleMessage);
|
||||
reject(new ConnectionError(canceller.cancelled));
|
||||
}
|
||||
function handleMessage(msg) {
|
||||
ws.removeEventListener('close', handleClose);
|
||||
try {
|
||||
const response = JSON.parse(msg.data);
|
||||
if (response.error) {
|
||||
@@ -156,13 +173,11 @@ function listenForResponse(ws, canceller) {
|
||||
resolve(response);
|
||||
}
|
||||
} catch (e) {
|
||||
ws.close();
|
||||
canceller.cancelled = true;
|
||||
canceller.error = e;
|
||||
reject(e);
|
||||
}
|
||||
}
|
||||
ws.addEventListener('message', handleMessage, { once: true });
|
||||
ws.addEventListener('close', handleClose, { once: true });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -176,6 +191,8 @@ async function upload(
|
||||
onprogress,
|
||||
canceller
|
||||
) {
|
||||
let size = 0;
|
||||
const start = Date.now();
|
||||
const host = window.location.hostname;
|
||||
const port = window.location.port;
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
@@ -203,31 +220,41 @@ async function upload(
|
||||
|
||||
const reader = stream.getReader();
|
||||
let state = await reader.read();
|
||||
let size = 0;
|
||||
while (!state.done) {
|
||||
const buf = state.value;
|
||||
if (canceller.cancelled) {
|
||||
throw canceller.error;
|
||||
ws.close();
|
||||
}
|
||||
|
||||
if (ws.readyState !== WebSocket.OPEN) {
|
||||
break;
|
||||
}
|
||||
const buf = state.value;
|
||||
ws.send(buf);
|
||||
|
||||
onprogress(size);
|
||||
size += buf.length;
|
||||
state = await reader.read();
|
||||
while (ws.bufferedAmount > ECE_RECORD_SIZE * 2) {
|
||||
while (
|
||||
ws.bufferedAmount > ECE_RECORD_SIZE * 2 &&
|
||||
ws.readyState === WebSocket.OPEN &&
|
||||
!canceller.cancelled
|
||||
) {
|
||||
await delay();
|
||||
}
|
||||
}
|
||||
const footer = new Uint8Array([0]);
|
||||
ws.send(footer);
|
||||
if (ws.readyState === WebSocket.OPEN) {
|
||||
ws.send(new Uint8Array([0])); //EOF
|
||||
}
|
||||
|
||||
await completedResponse;
|
||||
ws.close();
|
||||
uploadInfo.duration = Date.now() - start;
|
||||
return uploadInfo;
|
||||
} catch (e) {
|
||||
ws.close(4000);
|
||||
e.size = size;
|
||||
e.duration = Date.now() - start;
|
||||
throw e;
|
||||
} finally {
|
||||
if (![WebSocket.CLOSED, WebSocket.CLOSING].includes(ws.readyState)) {
|
||||
ws.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +271,6 @@ export function uploadWs(
|
||||
|
||||
return {
|
||||
cancel: function() {
|
||||
canceller.error = new Error(0);
|
||||
canceller.cancelled = true;
|
||||
},
|
||||
|
||||
@@ -284,7 +310,7 @@ async function downloadS(id, keychain, signal) {
|
||||
return response.body;
|
||||
}
|
||||
|
||||
async function tryDownloadStream(id, keychain, signal, tries = 1) {
|
||||
async function tryDownloadStream(id, keychain, signal, tries = 2) {
|
||||
try {
|
||||
const result = await downloadS(id, keychain, signal);
|
||||
return result;
|
||||
@@ -306,18 +332,19 @@ export function downloadStream(id, keychain) {
|
||||
}
|
||||
return {
|
||||
cancel,
|
||||
result: tryDownloadStream(id, keychain, controller.signal, 2)
|
||||
result: tryDownloadStream(id, keychain, controller.signal)
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////
|
||||
|
||||
function download(id, keychain, onprogress, canceller) {
|
||||
async function download(id, keychain, onprogress, canceller) {
|
||||
const auth = await keychain.authHeader();
|
||||
const xhr = new XMLHttpRequest();
|
||||
canceller.oncancel = function() {
|
||||
xhr.abort();
|
||||
};
|
||||
return new Promise(async function(resolve, reject) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
xhr.addEventListener('loadend', function() {
|
||||
canceller.oncancel = function() {};
|
||||
const authHeader = xhr.getResponseHeader('WWW-Authenticate');
|
||||
@@ -337,7 +364,6 @@ function download(id, keychain, onprogress, canceller) {
|
||||
onprogress(event.loaded);
|
||||
}
|
||||
});
|
||||
const auth = await keychain.authHeader();
|
||||
xhr.open('get', getApiUrl(`/api/download/blob/${id}`));
|
||||
xhr.setRequestHeader('Authorization', auth);
|
||||
xhr.responseType = 'blob';
|
||||
@@ -346,7 +372,7 @@ function download(id, keychain, onprogress, canceller) {
|
||||
});
|
||||
}
|
||||
|
||||
async function tryDownload(id, keychain, onprogress, canceller, tries = 1) {
|
||||
async function tryDownload(id, keychain, onprogress, canceller, tries = 2) {
|
||||
try {
|
||||
const result = await download(id, keychain, onprogress, canceller);
|
||||
return result;
|
||||
@@ -367,7 +393,7 @@ export function downloadFile(id, keychain, onprogress) {
|
||||
}
|
||||
return {
|
||||
cancel,
|
||||
result: tryDownload(id, keychain, onprogress, canceller, 2)
|
||||
result: tryDownload(id, keychain, onprogress, canceller)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -76,8 +76,8 @@ async function polyfillStreams() {
|
||||
}
|
||||
|
||||
export default async function getCapabilities() {
|
||||
const serviceWorker =
|
||||
'serviceWorker' in navigator && browserName() !== 'edge';
|
||||
const browser = browserName();
|
||||
const serviceWorker = 'serviceWorker' in navigator && browser !== 'edge';
|
||||
let crypto = await checkCrypto();
|
||||
const nativeStreams = checkStreams();
|
||||
let polyStreams = false;
|
||||
@@ -97,13 +97,16 @@ export default async function getCapabilities() {
|
||||
window.matchMedia('(display-mode: standalone)').matches ||
|
||||
navigator.standalone;
|
||||
|
||||
const mobileFirefox =
|
||||
browser === 'firefox' && /mobile/i.test(navigator.userAgent);
|
||||
|
||||
return {
|
||||
account,
|
||||
crypto,
|
||||
serviceWorker,
|
||||
streamUpload: nativeStreams || polyStreams,
|
||||
streamDownload:
|
||||
nativeStreams && serviceWorker && browserName() !== 'safari',
|
||||
nativeStreams && serviceWorker && browser !== 'safari' && !mobileFirefox,
|
||||
multifile: nativeStreams || polyStreams,
|
||||
share,
|
||||
standalone
|
||||
|
||||
@@ -76,7 +76,7 @@ export default function(state, emitter) {
|
||||
state.storage.remove(ownedFile.id);
|
||||
await ownedFile.del();
|
||||
} catch (e) {
|
||||
state.raven.captureException(e);
|
||||
state.sentry.captureException(e);
|
||||
}
|
||||
render();
|
||||
});
|
||||
@@ -176,14 +176,17 @@ export default function(state, emitter) {
|
||||
} catch (err) {
|
||||
if (err.message === '0') {
|
||||
//cancelled. do nothing
|
||||
const duration = Date.now() - start;
|
||||
metrics.cancelledUpload(archive, duration);
|
||||
metrics.cancelledUpload(archive, err.duration);
|
||||
render();
|
||||
} else {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err);
|
||||
state.raven.captureException(err);
|
||||
metrics.stoppedUpload(archive);
|
||||
state.sentry.withScope(scope => {
|
||||
scope.setExtra('duration', err.duration);
|
||||
scope.setExtra('size', err.size);
|
||||
state.sentry.captureException(err);
|
||||
});
|
||||
metrics.stoppedUpload(archive, err.duration);
|
||||
emitter.emit('pushState', '/error');
|
||||
}
|
||||
} finally {
|
||||
@@ -262,7 +265,12 @@ export default function(state, emitter) {
|
||||
state.transfer = null;
|
||||
const location = err.message === '404' ? '/404' : '/error';
|
||||
if (location === '/error') {
|
||||
state.raven.captureException(err);
|
||||
state.sentry.withScope(scope => {
|
||||
scope.setExtra('duration', err.duration);
|
||||
scope.setExtra('size', err.size);
|
||||
scope.setExtra('progress', err.progress);
|
||||
state.sentry.captureException(err);
|
||||
});
|
||||
const duration = Date.now() - start;
|
||||
metrics.stoppedDownload({
|
||||
size,
|
||||
|
||||
@@ -112,6 +112,7 @@ export default class FileReceiver extends Nanobus {
|
||||
}
|
||||
|
||||
async downloadStream(noSave = false) {
|
||||
const start = Date.now();
|
||||
const onprogress = p => {
|
||||
this.progress = [p, this.fileInfo.size];
|
||||
this.emit('progress');
|
||||
@@ -153,9 +154,7 @@ export default class FileReceiver extends Nanobus {
|
||||
const downloadPath = `/api/download/${this.fileInfo.id}`;
|
||||
let downloadUrl = getApiUrl(downloadPath);
|
||||
if (downloadUrl === downloadPath) {
|
||||
downloadUrl = `${location.protocol}//${location.host}/api/download/${
|
||||
this.fileInfo.id
|
||||
}`;
|
||||
downloadUrl = `${location.protocol}//${location.host}${downloadPath}`;
|
||||
}
|
||||
const a = document.createElement('a');
|
||||
a.href = downloadUrl;
|
||||
@@ -164,11 +163,29 @@ export default class FileReceiver extends Nanobus {
|
||||
}
|
||||
|
||||
let prog = 0;
|
||||
let hangs = 0;
|
||||
while (prog < this.fileInfo.size) {
|
||||
const msg = await this.sendMessageToSw({
|
||||
request: 'progress',
|
||||
id: this.fileInfo.id
|
||||
});
|
||||
if (msg.progress === prog) {
|
||||
hangs++;
|
||||
} else {
|
||||
hangs = 0;
|
||||
}
|
||||
if (hangs > 30) {
|
||||
// TODO: On Chrome we don't get a cancel
|
||||
// signal so one is indistinguishable from
|
||||
// a hang. We may be able to detect
|
||||
// which end is hung in the service worker
|
||||
// to improve on this.
|
||||
const e = new Error('hung download');
|
||||
e.duration = Date.now() - start;
|
||||
e.size = this.fileInfo.size;
|
||||
e.progress = prog;
|
||||
throw e;
|
||||
}
|
||||
prog = msg.progress;
|
||||
onprogress(prog);
|
||||
await delay(1000);
|
||||
|
||||
@@ -44,7 +44,6 @@ export default class FileSender extends Nanobus {
|
||||
}
|
||||
|
||||
async upload(archive, bearerToken) {
|
||||
const start = Date.now();
|
||||
if (this.cancelled) {
|
||||
throw new Error(0);
|
||||
}
|
||||
@@ -76,7 +75,6 @@ export default class FileSender extends Nanobus {
|
||||
this.emit('progress'); // HACK to kick MS Edge
|
||||
try {
|
||||
const result = await this.uploadRequest.result;
|
||||
const time = Date.now() - start;
|
||||
this.msg = 'notifyUploadEncryptDone';
|
||||
this.uploadRequest = null;
|
||||
this.progress = [1, 1];
|
||||
@@ -87,8 +85,8 @@ export default class FileSender extends Nanobus {
|
||||
name: archive.name,
|
||||
size: archive.size,
|
||||
manifest: archive.manifest,
|
||||
time: time,
|
||||
speed: archive.size / (time / 1000),
|
||||
time: result.duration,
|
||||
speed: archive.size / (result.duration / 1000),
|
||||
createdAt: Date.now(),
|
||||
expiresAt: Date.now() + archive.timeLimit * 1000,
|
||||
secretKey: secretKey,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FluentBundle } from 'fluent';
|
||||
import { FluentBundle } from '@fluent/bundle';
|
||||
|
||||
function makeBundle(locale, ftl) {
|
||||
const bundle = new FluentBundle(locale, { useIsolating: false });
|
||||
@@ -10,9 +10,9 @@ export async function getTranslator(locale) {
|
||||
const bundles = [];
|
||||
const { default: en } = await import('../public/locales/en-US/send.ftl');
|
||||
if (locale !== 'en-US') {
|
||||
const {
|
||||
default: ftl
|
||||
} = await import(`../public/locales/${locale}/send.ftl`);
|
||||
const { default: ftl } = await import(
|
||||
`../public/locales/${locale}/send.ftl`
|
||||
);
|
||||
bundles.push(makeBundle(locale, ftl));
|
||||
}
|
||||
bundles.push(makeBundle('en-US', en));
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
@tailwind preflight;
|
||||
@tailwind base;
|
||||
|
||||
html {
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
@tailwind components;
|
||||
|
||||
:not(input) {
|
||||
@@ -311,6 +316,7 @@ select {
|
||||
}
|
||||
|
||||
.signin {
|
||||
backface-visibility: hidden;
|
||||
border-radius: 6px;
|
||||
transition-property: transform, background-color;
|
||||
transition-duration: 250ms;
|
||||
|
||||
14
app/main.js
14
app/main.js
@@ -1,7 +1,7 @@
|
||||
/* global DEFAULTS LIMITS PREFS */
|
||||
import 'core-js';
|
||||
import 'fast-text-encoding'; // MS Edge support
|
||||
import 'fluent-intl-polyfill';
|
||||
import 'intl-pluralrules';
|
||||
import choo from 'choo';
|
||||
import nanotiming from 'nanotiming';
|
||||
import routes from './routes';
|
||||
@@ -12,15 +12,15 @@ import pasteManager from './pasteManager';
|
||||
import storage from './storage';
|
||||
import metrics from './metrics';
|
||||
import experiments from './experiments';
|
||||
import Raven from 'raven-js';
|
||||
import * as Sentry from '@sentry/browser';
|
||||
import './main.css';
|
||||
import User from './user';
|
||||
import { getTranslator } from './locale';
|
||||
import Archive from './archive';
|
||||
import { setTranslate, locale } from './utils';
|
||||
|
||||
if (navigator.doNotTrack !== '1' && window.RAVEN_CONFIG) {
|
||||
Raven.config(window.SENTRY_ID, window.RAVEN_CONFIG).install();
|
||||
if (navigator.doNotTrack !== '1' && window.SENTRY_CONFIG) {
|
||||
Sentry.init(window.SENTRY_CONFIG);
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
@@ -47,6 +47,7 @@ if (process.env.NODE_ENV === 'production') {
|
||||
|
||||
const translate = await getTranslator(locale());
|
||||
setTranslate(translate);
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
window.initialState = {
|
||||
LIMITS,
|
||||
DEFAULTS,
|
||||
@@ -55,13 +56,14 @@ if (process.env.NODE_ENV === 'production') {
|
||||
capabilities,
|
||||
translate,
|
||||
storage,
|
||||
raven: Raven,
|
||||
sentry: Sentry,
|
||||
user: new User(storage, LIMITS, window.AUTH_CONFIG),
|
||||
transfer: null,
|
||||
fileInfo: null
|
||||
};
|
||||
|
||||
const app = routes(choo());
|
||||
const app = routes(choo({ hash: true }));
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
window.app = app;
|
||||
app.use(experiments);
|
||||
app.use(metrics);
|
||||
|
||||
@@ -107,9 +107,10 @@ function completedUpload(archive, duration) {
|
||||
});
|
||||
}
|
||||
|
||||
function stoppedUpload(archive) {
|
||||
function stoppedUpload(archive, duration = 0) {
|
||||
return addEvent('client_upload', {
|
||||
download_limit: archive.dlimit,
|
||||
duration: sizeOrder(duration),
|
||||
file_count: archive.numFiles,
|
||||
password_protected: !!archive.password,
|
||||
size: sizeOrder(archive.size),
|
||||
|
||||
@@ -2,7 +2,7 @@ const choo = require('choo');
|
||||
const download = require('./ui/download');
|
||||
const body = require('./ui/body');
|
||||
|
||||
module.exports = function(app = choo()) {
|
||||
module.exports = function(app = choo({ hash: true })) {
|
||||
app.route('/', body(require('./ui/home')));
|
||||
app.route('/download/:id', body(download));
|
||||
app.route('/download/:id/:key', body(download));
|
||||
@@ -13,6 +13,7 @@ module.exports = function(app = choo()) {
|
||||
app.route('/oauth', function(state, emit) {
|
||||
emit('authenticate', state.query.code, state.query.state);
|
||||
});
|
||||
app.route('/login', body(require('./ui/home')));
|
||||
app.route('*', body(require('./ui/notFound')));
|
||||
return app;
|
||||
};
|
||||
|
||||
@@ -11,13 +11,14 @@ const map = new Map();
|
||||
const IMAGES = /.*\.(png|svg|jpg)$/;
|
||||
const VERSIONED_ASSET = /\.[A-Fa-f0-9]{8}\.(js|css|png|svg|jpg)$/;
|
||||
const DOWNLOAD_URL = /\/api\/download\/([A-Fa-f0-9]{4,})/;
|
||||
const FONT = /\.woff2?$/;
|
||||
|
||||
self.addEventListener('install', event => {
|
||||
event.waitUntil(precache());
|
||||
});
|
||||
|
||||
self.addEventListener('activate', event => {
|
||||
event.waitUntil(self.clients.claim());
|
||||
event.waitUntil(self.clients.claim().then(cleanCache));
|
||||
});
|
||||
|
||||
async function decryptStream(id) {
|
||||
@@ -83,16 +84,23 @@ async function decryptStream(id) {
|
||||
}
|
||||
|
||||
async function precache() {
|
||||
const cache = await caches.open(version);
|
||||
const images = assets.match(IMAGES);
|
||||
await cache.addAll(images);
|
||||
return self.skipWaiting();
|
||||
}
|
||||
|
||||
async function cleanCache() {
|
||||
const oldCaches = await caches.keys();
|
||||
for (const c of oldCaches) {
|
||||
if (c !== version) {
|
||||
await caches.delete(c);
|
||||
}
|
||||
}
|
||||
const cache = await caches.open(version);
|
||||
const images = assets.match(IMAGES);
|
||||
await cache.addAll(images);
|
||||
return self.skipWaiting();
|
||||
}
|
||||
|
||||
function cacheable(url) {
|
||||
return VERSIONED_ASSET.test(url) || FONT.test(url);
|
||||
}
|
||||
|
||||
async function cachedOrFetched(req) {
|
||||
@@ -102,7 +110,7 @@ async function cachedOrFetched(req) {
|
||||
return cached;
|
||||
}
|
||||
const fetched = await fetch(req);
|
||||
if (fetched.ok && VERSIONED_ASSET.test(req.url)) {
|
||||
if (fetched.ok && cacheable(req.url)) {
|
||||
cache.put(req, fetched.clone());
|
||||
}
|
||||
return fetched;
|
||||
@@ -115,7 +123,7 @@ self.onfetch = event => {
|
||||
const dlmatch = DOWNLOAD_URL.exec(url.pathname);
|
||||
if (dlmatch) {
|
||||
event.respondWith(decryptStream(dlmatch[1]));
|
||||
} else if (VERSIONED_ASSET.test(url.pathname)) {
|
||||
} else if (cacheable(url.pathname)) {
|
||||
event.respondWith(cachedOrFetched(req));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* global ReadableStream TransformStream */
|
||||
/* global TransformStream */
|
||||
|
||||
export function transformStream(readable, transformer, oncancel) {
|
||||
try {
|
||||
|
||||
@@ -85,7 +85,7 @@ class Account extends Component {
|
||||
/>
|
||||
<ul
|
||||
id="accountMenu"
|
||||
class="invisible list-reset absolute pin-t pin-r mt-10 pt-2 pb-2 bg-white shadow-md whitespace-no-wrap outline-none z-50"
|
||||
class="invisible absolute top-0 right-0 mt-10 pt-2 pb-2 bg-white shadow-md whitespace-no-wrap outline-none z-50"
|
||||
onblur="${e => this.hideMenu(e)}"
|
||||
>
|
||||
<li class="p-2 text-grey-dark">${user.email}</li>
|
||||
|
||||
@@ -120,7 +120,7 @@ function fileInfo(file, action) {
|
||||
function archiveInfo(archive, action) {
|
||||
return html`
|
||||
<p class="w-full flex items-center">
|
||||
<img class="mr-3 flex-no-shrink" src="${assets.get('blue_file.svg')}"/>
|
||||
<img class="mr-3 flex-shrink-0" src="${assets.get('blue_file.svg')}"/>
|
||||
<p class="flex-grow">
|
||||
<h1 class="text-base font-medium word-break-all">${archive.name}</h1>
|
||||
<div class="text-sm font-normal opacity-75 pt-1">${bytes(
|
||||
@@ -155,7 +155,7 @@ function archiveDetails(translate, archive) {
|
||||
num: archive.manifest.files.length
|
||||
})}
|
||||
</summary>
|
||||
${list(archive.manifest.files.map(f => fileInfo(f)), 'list-reset')}
|
||||
${list(archive.manifest.files.map(f => fileInfo(f)))}
|
||||
</details>
|
||||
`;
|
||||
}
|
||||
@@ -213,7 +213,7 @@ module.exports = function(state, emit, archive) {
|
||||
html`
|
||||
<input
|
||||
type="image"
|
||||
class="self-start flex-no-shrink text-white hover:opacity-75 focus:outline"
|
||||
class="self-start flex-shrink-0 text-white hover:opacity-75 focus:outline"
|
||||
alt="${state.translate('deleteButtonHover')}"
|
||||
title="${state.translate('deleteButtonHover')}"
|
||||
src="${assets.get('close-16.svg')}"
|
||||
@@ -256,9 +256,7 @@ module.exports = function(state, emit, archive) {
|
||||
try {
|
||||
await navigator.share({
|
||||
title: state.translate('-send-brand'),
|
||||
text: `Download "${
|
||||
archive.name
|
||||
}" with Firefox Send: simple, safe file sharing`,
|
||||
text: `Download "${archive.name}" with Firefox Send: simple, safe file sharing`,
|
||||
//state.translate('shareMessage', { name }),
|
||||
url: archive.url
|
||||
});
|
||||
@@ -278,11 +276,11 @@ module.exports.wip = function(state, emit) {
|
||||
.map(f =>
|
||||
fileInfo(f, remove(f, state.translate('deleteButtonHover')))
|
||||
),
|
||||
'flex-shrink bg-grey-lightest rounded-t list-reset overflow-y-auto px-6 py-4 md:h-full md:max-h-half-screen',
|
||||
'flex-shrink bg-grey-lightest rounded-t overflow-y-auto px-6 py-4 md:h-full md:max-h-half-screen',
|
||||
'bg-white px-2 my-2 shadow-light rounded'
|
||||
)}
|
||||
<div
|
||||
class="flex-no-shrink flex-grow flex items-end p-4 bg-grey-lightest rounded-b mb-1 font-medium"
|
||||
class="flex-shrink-0 flex-grow flex items-end p-4 bg-grey-lightest rounded-b mb-1 font-medium"
|
||||
>
|
||||
<input
|
||||
id="file-upload"
|
||||
@@ -315,7 +313,7 @@ module.exports.wip = function(state, emit) {
|
||||
${expiryOptions(state, emit)} ${password(state, emit)}
|
||||
<button
|
||||
id="upload-btn"
|
||||
class="btn rounded-lg flex-no-shrink focus:outline"
|
||||
class="btn rounded-lg flex-shrink-0 focus:outline"
|
||||
title="${state.translate('uploadButton')}"
|
||||
onclick="${upload}"
|
||||
>
|
||||
@@ -509,7 +507,7 @@ module.exports.preview = function(state, emit) {
|
||||
</div>
|
||||
<button
|
||||
id="download-btn"
|
||||
class="btn rounded-lg mt-4 w-full flex-no-shrink focus:outline"
|
||||
class="btn rounded-lg mt-4 w-full flex-shrink-0 focus:outline"
|
||||
title="${state.translate('downloadButtonLabel')}"
|
||||
onclick=${download}
|
||||
>
|
||||
|
||||
@@ -7,7 +7,7 @@ module.exports = function(name, url) {
|
||||
<send-copy-dialog
|
||||
class="flex flex-col items-center text-center p-4 max-w-sm m-auto"
|
||||
>
|
||||
<h1 class="font-bold my-4">
|
||||
<h1 class="text-3xl font-bold my-4">
|
||||
${state.translate('notifyUploadEncryptDone')}
|
||||
</h1>
|
||||
<p class="font-normal leading-normal text-grey-darkest word-break-all">
|
||||
@@ -22,7 +22,7 @@ module.exports = function(name, url) {
|
||||
readonly="true"
|
||||
/>
|
||||
<button
|
||||
class="btn rounded-lg w-full flex-no-shrink focus:outline"
|
||||
class="btn rounded-lg w-full flex-shrink-0 focus:outline"
|
||||
onclick="${copy}"
|
||||
title="${state.translate('copyLinkButton')}"
|
||||
>
|
||||
|
||||
@@ -22,7 +22,9 @@ function downloading(state, emit) {
|
||||
<div
|
||||
class="flex flex-col w-full h-full items-center md:justify-center md:-mt-8"
|
||||
>
|
||||
<h1 class="mb-4">${state.translate('downloadingTitle')}</h1>
|
||||
<h1 class="text-3xl font-bold mb-4">
|
||||
${state.translate('downloadingTitle')}
|
||||
</h1>
|
||||
${archiveTile.downloading(state, emit)}
|
||||
</div>
|
||||
`;
|
||||
@@ -36,7 +38,9 @@ function preview(state, emit) {
|
||||
<div
|
||||
class="flex flex-col w-full max-w-md h-full mx-auto items-center justify-center"
|
||||
>
|
||||
<h1 class="mb-4">${state.translate('downloadTitle')}</h1>
|
||||
<h1 class="text-3xl font-bold mb-4">
|
||||
${state.translate('downloadTitle')}
|
||||
</h1>
|
||||
<p class="w-full text-grey-darkest text-center leading-normal">
|
||||
${state.translate('downloadDescription')}
|
||||
</p>
|
||||
|
||||
@@ -7,7 +7,7 @@ module.exports = function(state) {
|
||||
id="download-complete"
|
||||
class="flex flex-col items-center justify-center h-full w-full bg-white p-2"
|
||||
>
|
||||
<h1 class="text-center font-bold my-2">
|
||||
<h1 class="text-center text-3xl font-bold my-2">
|
||||
${state.translate('downloadFinish')}
|
||||
</h1>
|
||||
<img src="${assets.get('completed.svg')}" class="my-12 h-48" />
|
||||
|
||||
@@ -8,7 +8,9 @@ module.exports = function(state, emit) {
|
||||
<div
|
||||
class="h-full w-full flex flex-col items-center justify-center bg-white py-8 max-w-md mx-auto"
|
||||
>
|
||||
<h1 class="mb-4">${state.translate('downloadTitle')}</h1>
|
||||
<h1 class="text-3xl font-bold mb-4">
|
||||
${state.translate('downloadTitle')}
|
||||
</h1>
|
||||
<p class="w-full mb-4 text-center text-grey-darkest leading-normal">
|
||||
${state.translate('downloadDescription')}
|
||||
</p>
|
||||
|
||||
@@ -9,7 +9,7 @@ module.exports = function(state, emit) {
|
||||
<section
|
||||
class="flex flex-col items-center justify-center h-full w-full p-6 md:p-8 overflow-hidden md:rounded-xl md:shadow-big"
|
||||
>
|
||||
<h1 class="text-center font-bold my-2">
|
||||
<h1 class="text-center text-3xl font-bold my-2">
|
||||
${state.translate('errorPageHeader')}
|
||||
</h1>
|
||||
<img class="my-12 h-48" src="${assets.get('error.svg')}" />
|
||||
|
||||
@@ -28,7 +28,7 @@ class Footer extends Component {
|
||||
Mozilla
|
||||
</a>
|
||||
<ul
|
||||
class="list-reset flex flex-col md:flex-row items-start md:items-center md:justify-end"
|
||||
class="flex flex-col md:flex-row items-start md:items-center md:justify-end"
|
||||
>
|
||||
<li class="m-2">
|
||||
<a href="https://www.mozilla.org/about/legal/terms/services/#send">
|
||||
|
||||
@@ -20,11 +20,7 @@ module.exports = function(state, emit) {
|
||||
const right =
|
||||
archives.length === 0
|
||||
? intro(state)
|
||||
: list(
|
||||
archives,
|
||||
'list-reset p-2 h-full overflow-y-auto w-full',
|
||||
'mb-4 w-full'
|
||||
);
|
||||
: list(archives, 'p-2 h-full overflow-y-auto w-full', 'mb-4 w-full');
|
||||
|
||||
return html`
|
||||
<main class="main">
|
||||
|
||||
@@ -7,7 +7,7 @@ module.exports = function intro(state) {
|
||||
class="flex flex-col items-center justify-center bg-white px-6 md:py-0 py-6 mb-0 h-full w-full"
|
||||
>
|
||||
<div class="mt-12 flex flex-col h-full">
|
||||
<h1 class="font-bold md:pb-2">
|
||||
<h1 class="text-3xl font-bold md:pb-2">
|
||||
${state.translate('introTitle')}
|
||||
</h1>
|
||||
<p class="max-w-sm leading-loose mt-6 md:mt-2 md:pr-14">
|
||||
|
||||
@@ -8,7 +8,9 @@ module.exports = function(state, emit) {
|
||||
<div
|
||||
class="flex flex-col items-center bg-white m-4 px-6 py-8 border border-grey-light md:border-none md:px-12 md:py-16 shadow w-full md:h-full"
|
||||
>
|
||||
<h1 class="text-center">${state.translate('legalTitle')}</h1>
|
||||
<h1 class="text-center text-3xl font-bold">
|
||||
${state.translate('legalTitle')}
|
||||
</h1>
|
||||
<p class="mt-2">${state.translate('legalDateStamp')}</p>
|
||||
<div class="overflow-y-scroll py-8 px-12">
|
||||
<p class="leading-normal">
|
||||
|
||||
@@ -3,11 +3,11 @@ const html = require('choo/html');
|
||||
module.exports = function(state, emit) {
|
||||
return html`
|
||||
<send-modal
|
||||
class="absolute pin flex items-center justify-center overflow-hidden z-40 bg-white md:rounded-xl md:my-8"
|
||||
class="absolute inset-0 flex items-center justify-center overflow-hidden z-40 bg-white md:rounded-xl md:my-8"
|
||||
onclick="${close}"
|
||||
>
|
||||
<div
|
||||
class="h-full w-full max-h-screen absolute pin-t flex items-center justify-center"
|
||||
class="h-full w-full max-h-screen absolute top-0 flex items-center justify-center"
|
||||
>
|
||||
<div class="w-full" onclick="${e => e.stopPropagation()}">
|
||||
${state.modal(state, emit, close)}
|
||||
|
||||
@@ -8,7 +8,9 @@ module.exports = function(state, emit) {
|
||||
<div
|
||||
class="flex flex-col w-full max-w-md h-full mx-auto items-center justify-center"
|
||||
>
|
||||
<h1 class="mb-4">${state.translate('downloadTitle')}</h1>
|
||||
<h1 class="mb-4 text-3xl font-bold">${state.translate(
|
||||
'downloadTitle'
|
||||
)}</h1>
|
||||
<p
|
||||
class="w-full p-2 border border-yellow-light rounded md:w-4/5 text-orange-dark bg-yellow-lighter text-center leading-normal"
|
||||
>
|
||||
@@ -17,7 +19,7 @@ module.exports = function(state, emit) {
|
||||
<form class="md:w-128" onsubmit=${submit}>
|
||||
<fieldset class="border rounded p-4 my-4" onchange=${optionChanged}>
|
||||
<div class="flex items-center mb-2">
|
||||
<img class="mr-3 flex-no-shrink" src="${assets.get(
|
||||
<img class="mr-3 flex-shrink-0" src="${assets.get(
|
||||
'blue_file.svg'
|
||||
)}"/>
|
||||
<p class="flex-grow">
|
||||
@@ -49,7 +51,7 @@ module.exports = function(state, emit) {
|
||||
</div>
|
||||
</fieldset>
|
||||
<input
|
||||
class="btn rounded-lg w-full flex flex-no-shrink items-center justify-center"
|
||||
class="btn rounded-lg w-full flex flex-shrink-0 items-center justify-center"
|
||||
value="${state.translate('copyLinkButton')}"
|
||||
title="${state.translate('copyLinkButton')}"
|
||||
type="submit" />
|
||||
|
||||
@@ -9,7 +9,7 @@ module.exports = function(state, emit) {
|
||||
<section
|
||||
class="flex flex-col items-center justify-center h-full w-full p-6 md:p-8 overflow-hidden md:rounded-xl md:shadow-big"
|
||||
>
|
||||
<h1 class="text-center font-bold my-2">
|
||||
<h1 class="text-center text-3xl font-bold my-2">
|
||||
${state.translate('expiredTitle')}
|
||||
</h1>
|
||||
<img src="${assets.get('notFound.svg')}" class="my-12" />
|
||||
|
||||
@@ -4,9 +4,11 @@ module.exports = function(message) {
|
||||
return function(state, emit, close) {
|
||||
return html`
|
||||
<send-ok-dialog class="flex flex-col max-w-sm p-4 m-auto">
|
||||
<h2 class="text-center m-8 leading-normal">${message}</h2>
|
||||
<h2 class="text-center text-xl font-bold m-8 leading-normal">
|
||||
${message}
|
||||
</h2>
|
||||
<button
|
||||
class="btn rounded-lg w-full flex-no-shrink"
|
||||
class="btn rounded-lg w-full flex-shrink-0"
|
||||
onclick="${close}"
|
||||
title="${state.translate('okButton')}"
|
||||
>
|
||||
|
||||
@@ -6,7 +6,7 @@ module.exports = function(name, url) {
|
||||
<send-share-dialog
|
||||
class="flex flex-col items-center text-center p-4 max-w-sm m-auto"
|
||||
>
|
||||
<h1 class="font-bold my-4">
|
||||
<h1 class="text-3xl font-bold my-4">
|
||||
${state.translate('notifyUploadEncryptDone')}
|
||||
</h1>
|
||||
<p class="font-normal leading-normal text-grey-darkest word-break-all">
|
||||
@@ -21,7 +21,7 @@ module.exports = function(name, url) {
|
||||
readonly="true"
|
||||
/>
|
||||
<button
|
||||
class="btn rounded-lg w-full flex-no-shrink focus:outline"
|
||||
class="btn rounded-lg w-full flex-shrink-0 focus:outline"
|
||||
onclick="${share}"
|
||||
title="${state.translate('shareLinkButton')}"
|
||||
>
|
||||
|
||||
@@ -14,9 +14,9 @@ module.exports = function(trigger) {
|
||||
>
|
||||
<img src="${assets.get('master-logo.svg')}" class="h-16 mt-1 mb-4" />
|
||||
<section
|
||||
class="flex flex-col flex-no-shrink self-center lg:mx-6 lg:max-w-xs"
|
||||
class="flex flex-col flex-shrink-0 self-center lg:mx-6 lg:max-w-xs"
|
||||
>
|
||||
<h1 class="font-bold text-center lg:text-left">
|
||||
<h1 class="text-3xl font-bold text-center lg:text-left">
|
||||
${state.translate('accountBenefitTitle')}
|
||||
</h1>
|
||||
<ul
|
||||
@@ -46,7 +46,7 @@ module.exports = function(trigger) {
|
||||
placeholder=${state.translate('emailPlaceholder')}
|
||||
/>
|
||||
<input
|
||||
class="btn rounded-lg w-full flex flex-no-shrink items-center justify-center"
|
||||
class="btn rounded-lg w-full flex flex-shrink-0 items-center justify-center"
|
||||
value="${state.translate('signInOnlyButton')}"
|
||||
title="${state.translate('signInOnlyButton')}"
|
||||
id="email-submit"
|
||||
|
||||
@@ -13,7 +13,7 @@ module.exports = function() {
|
||||
<send-survey-dialog
|
||||
class="flex flex-col items-center text-center p-4 max-w-sm m-auto"
|
||||
>
|
||||
<h1 class="font-bold my-4">
|
||||
<h1 class="text-3xl font-bold my-4">
|
||||
Tell us what you think.
|
||||
</h1>
|
||||
<p class="font-normal leading-normal text-grey-darkest px-4">
|
||||
@@ -21,7 +21,7 @@ module.exports = function() {
|
||||
it better.
|
||||
</p>
|
||||
<a
|
||||
class="btn rounded-lg w-full flex-no-shrink focus:outline my-5"
|
||||
class="btn rounded-lg w-full flex-shrink-0 focus:outline my-5"
|
||||
onclick="${() => emit('closeModal')}"
|
||||
title="Give feedback"
|
||||
href="${surveyUrl}"
|
||||
|
||||
@@ -29,7 +29,7 @@ module.exports = function(state, emit) {
|
||||
<section
|
||||
class="flex flex-col items-center justify-center text-center bg-white m-6 px-6 py-8 border border-grey-light md:border-none md:px-12 md:py-16 shadow w-full md:h-full"
|
||||
>
|
||||
<h1 class="">${strings.header}</h1>
|
||||
<h1 class="text-3xl font-bold">${strings.header}</h1>
|
||||
<p class="mt-4 mb-8 max-w-md leading-normal">${strings.description}</p>
|
||||
${why}
|
||||
<a href="${url}" class="btn rounded-lg mt-8 px-8">
|
||||
|
||||
68
docs/deployment.md
Normal file
68
docs/deployment.md
Normal file
@@ -0,0 +1,68 @@
|
||||
## Requirements
|
||||
This document describes how to do a full deployment of Firefox Send on your own Linux server. You will need:
|
||||
|
||||
* A working (and ideally somewhat recent) installation of NodeJS and NPM
|
||||
* GIT
|
||||
* An Apache webserver
|
||||
* Optionally telnet, to be able to quickly check your installation
|
||||
|
||||
For Debian/Ubuntu systems this probably just means something like this:
|
||||
|
||||
* apt install git apache2 nodejs npm telnet
|
||||
|
||||
## Building
|
||||
* We assume an already configured virtual-host on your webserver with an existing empty htdocs folder
|
||||
* First, remove that htdocs folder - we will replace it with Firefox Send's version now
|
||||
* git clone https://github.com/mozilla/send.git htdocs
|
||||
* Make now sure you are NOT root but rather the user your webserver is serving files under (e.g. "su www-data" or whoever the owner of your htdocs folder is)
|
||||
* npm install
|
||||
* npm run build
|
||||
|
||||
## Running
|
||||
To have a permanently running version of Firefox Send as a background process:
|
||||
|
||||
* Create a file "run.sh" with:
|
||||
```
|
||||
#!/bin/bash
|
||||
nohup su www-data -c "npm run prod" 2>/dev/null &
|
||||
```
|
||||
* chmod +x run.sh
|
||||
* ./run.sh
|
||||
|
||||
Now the Firefox Send backend should be running on port 1443. You can check with:
|
||||
* telnet localhost 1443
|
||||
|
||||
## Reverse Proxy
|
||||
Of course, we don't want to expose the service on port 1443. Instead we want our normal webserver to forward all requests to Firefox send ("Reverse proxy").
|
||||
|
||||
# Apache webserver
|
||||
|
||||
* a2enmod proxy
|
||||
* a2enmod proxy_http
|
||||
* a2enmod proxy_wstunnel
|
||||
|
||||
In your Apache virtual host configuration file, insert this:
|
||||
|
||||
```
|
||||
# Enable rewrite engine
|
||||
RewriteEngine on
|
||||
|
||||
# Make sure the original domain name is forwarded to Send
|
||||
# Otherwise the generated URLs will be wrong
|
||||
ProxyPreserveHost on
|
||||
|
||||
# Make sure the generated URL is https://
|
||||
RequestHeader set X-Forwarded-Proto https
|
||||
|
||||
# If it's a normal file (e.g. PNG, CSS) just return it
|
||||
RewriteCond %{REQUEST_FILENAME} -f
|
||||
RewriteRule .* - [L]
|
||||
|
||||
# If it's a websocket connection, redirect it to a Send WS connection
|
||||
RewriteCond %{HTTP:Upgrade} =websocket [NC]
|
||||
RewriteRule /(.*) ws://127.0.0.1:1443/$1 [P,L]
|
||||
|
||||
# Otherwise redirect it to a normal HTTP connection
|
||||
RewriteRule ^/(.*)$ http://127.0.0.1:1443/$1 [P,QSA]
|
||||
ProxyPassReverse "/" "http://127.0.0.1:1443"
|
||||
```
|
||||
5931
package-lock.json
generated
5931
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
112
package.json
112
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "firefox-send",
|
||||
"description": "File Sharing Experiment",
|
||||
"version": "3.0.12",
|
||||
"version": "3.0.17",
|
||||
"author": "Mozilla (https://mozilla.org)",
|
||||
"repository": "mozilla/send",
|
||||
"homepage": "https://github.com/mozilla/send/",
|
||||
@@ -35,7 +35,8 @@
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged",
|
||||
"pre-push": "npm test",
|
||||
"post-merge": "npm install"
|
||||
"post-merge": "npm install",
|
||||
"post-checkout": "scripts/sync-npm-dependencies.sh"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
@@ -60,65 +61,66 @@
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.4.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.4.4",
|
||||
"@babel/core": "^7.5.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.5.5",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||
"@babel/preset-env": "^7.4.5",
|
||||
"@babel/preset-env": "^7.5.5",
|
||||
"@dannycoates/webcrypto-liner": "^0.1.37",
|
||||
"@fullhuman/postcss-purgecss": "^1.2.0",
|
||||
"@mattiasbuelens/web-streams-polyfill": "0.2.1",
|
||||
"@sentry/browser": "^5.6.3",
|
||||
"asmcrypto.js": "^0.22.0",
|
||||
"babel-loader": "^8.0.6",
|
||||
"babel-plugin-istanbul": "^5.1.4",
|
||||
"base64-js": "^1.3.0",
|
||||
"babel-plugin-istanbul": "^5.2.0",
|
||||
"base64-js": "^1.3.1",
|
||||
"content-disposition": "^0.5.3",
|
||||
"copy-webpack-plugin": "^5.0.3",
|
||||
"core-js": "^3.1.3",
|
||||
"copy-webpack-plugin": "^5.0.4",
|
||||
"core-js": "^3.2.1",
|
||||
"crc": "^3.8.0",
|
||||
"cross-env": "^5.2.0",
|
||||
"css-loader": "^2.1.1",
|
||||
"cross-env": "^5.2.1",
|
||||
"css-loader": "^3.2.0",
|
||||
"css-mqpacker": "^7.0.0",
|
||||
"cssnano": "^4.1.10",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-plugin-mocha": "^5.3.0",
|
||||
"eslint-plugin-node": "^8.0.1",
|
||||
"eslint": "^6.3.0",
|
||||
"eslint-config-prettier": "^6.2.0",
|
||||
"eslint-plugin-mocha": "^6.1.0",
|
||||
"eslint-plugin-node": "^9.2.0",
|
||||
"eslint-plugin-security": "^1.4.0",
|
||||
"expose-loader": "^0.7.5",
|
||||
"extract-loader": "^3.1.0",
|
||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||
"fast-text-encoding": "^1.0.0",
|
||||
"file-loader": "^3.0.1",
|
||||
"fluent-intl-polyfill": "^0.1.0",
|
||||
"file-loader": "^4.2.0",
|
||||
"git-rev-sync": "^1.12.0",
|
||||
"html-loader": "^0.5.5",
|
||||
"http_ece": "^1.1.0",
|
||||
"husky": "^2.3.0",
|
||||
"lint-staged": "^8.1.7",
|
||||
"mocha": "^6.1.4",
|
||||
"husky": "^3.0.5",
|
||||
"intl-pluralrules": "^1.0.3",
|
||||
"lint-staged": "^9.2.5",
|
||||
"mocha": "^6.2.0",
|
||||
"morgan": "^1.9.1",
|
||||
"nanobus": "^4.4.0",
|
||||
"nanohtml": "^1.6.2",
|
||||
"nanohtml": "^1.8.1",
|
||||
"nanotiming": "^7.3.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"nyc": "^14.1.1",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"postcss-preset-env": "^6.6.0",
|
||||
"prettier": "^1.17.1",
|
||||
"proxyquire": "^2.1.0",
|
||||
"puppeteer": "^1.17.0",
|
||||
"raven-js": "^3.27.1",
|
||||
"raw-loader": "^2.0.0",
|
||||
"redis-mock": "^0.43.0",
|
||||
"rimraf": "^2.6.3",
|
||||
"postcss-preset-env": "^6.7.0",
|
||||
"prettier": "^1.18.2",
|
||||
"proxyquire": "^2.1.3",
|
||||
"puppeteer": "^1.19.0",
|
||||
"raw-loader": "^3.1.0",
|
||||
"redis-mock": "^0.46.0",
|
||||
"rimraf": "^3.0.0",
|
||||
"script-loader": "^0.7.2",
|
||||
"sinon": "^7.3.2",
|
||||
"sinon": "^7.4.2",
|
||||
"string-hash": "^1.1.3",
|
||||
"stylelint": "^10.0.1",
|
||||
"stylelint": "^10.1.0",
|
||||
"stylelint-config-standard": "^18.3.0",
|
||||
"stylelint-no-unsupported-browser-features": "^3.0.2",
|
||||
"svgo": "^1.2.2",
|
||||
"svgo-loader": "^2.2.0",
|
||||
"tailwindcss": "^0.7.4",
|
||||
"svgo": "^1.3.0",
|
||||
"svgo-loader": "^2.2.1",
|
||||
"tailwindcss": "^1.1.2",
|
||||
"val-loader": "^1.1.1",
|
||||
"wdio-docker-service": "^1.4.2",
|
||||
"wdio-dot-reporter": "0.0.10",
|
||||
@@ -128,39 +130,41 @@
|
||||
"wdio-selenium-standalone-service": "0.0.12",
|
||||
"wdio-spec-reporter": "^0.1.5",
|
||||
"webdriverio": "^4.14.4",
|
||||
"webpack": "^4.32.2",
|
||||
"webpack-cli": "^3.3.2",
|
||||
"webpack-dev-middleware": "^3.7.0",
|
||||
"webpack-dev-server": "^3.4.1",
|
||||
"webpack": "4.38.0",
|
||||
"webpack-cli": "^3.3.7",
|
||||
"webpack-dev-middleware": "^3.7.1",
|
||||
"webpack-dev-server": "^3.8.0",
|
||||
"webpack-manifest-plugin": "^2.0.4",
|
||||
"webpack-unassert-loader": "^1.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@google-cloud/storage": "^2.5.0",
|
||||
"aws-sdk": "^2.465.0",
|
||||
"@dannycoates/express-ws": "^5.0.3",
|
||||
"@fluent/bundle": "^0.13.0",
|
||||
"@fluent/langneg": "^0.3.0",
|
||||
"@google-cloud/storage": "^3.2.1",
|
||||
"@sentry/node": "^5.6.2",
|
||||
"aws-sdk": "^2.523.0",
|
||||
"body-parser": "^1.19.0",
|
||||
"choo": "^6.13.3",
|
||||
"choo": "^7.0.0",
|
||||
"cldr-core": "^35.1.0",
|
||||
"convict": "^4.4.1",
|
||||
"configstore": "github:dannycoates/configstore#master",
|
||||
"convict": "^5.1.0",
|
||||
"express": "^4.17.1",
|
||||
"express-ws": "github:dannycoates/express-ws",
|
||||
"fluent": "^0.12.0",
|
||||
"fluent-langneg": "^0.1.1",
|
||||
"fxa-geodb": "^1.0.4",
|
||||
"helmet": "^3.18.0",
|
||||
"helmet": "^3.21.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mozlog": "^2.2.0",
|
||||
"node-fetch": "^2.6.0",
|
||||
"raven": "^2.6.4",
|
||||
"redis": "^2.8.0",
|
||||
"selenium-standalone": "^6.15.6",
|
||||
"ua-parser-js": "^0.7.19",
|
||||
"websocket-stream": "^5.5.0"
|
||||
"ua-parser-js": "^0.7.20"
|
||||
},
|
||||
"availableLanguages": [
|
||||
"en-US",
|
||||
"ar",
|
||||
"ast",
|
||||
"bn-BD",
|
||||
"bn",
|
||||
"br",
|
||||
"ca",
|
||||
"cak",
|
||||
"cs",
|
||||
@@ -175,9 +179,12 @@
|
||||
"es-CL",
|
||||
"es-ES",
|
||||
"es-MX",
|
||||
"et",
|
||||
"eu",
|
||||
"fi",
|
||||
"fr",
|
||||
"fy-NL",
|
||||
"he",
|
||||
"hr",
|
||||
"hsb",
|
||||
"hu",
|
||||
@@ -189,8 +196,12 @@
|
||||
"kab",
|
||||
"ko",
|
||||
"lt",
|
||||
"ml",
|
||||
"nb-NO",
|
||||
"nl",
|
||||
"nn-NO",
|
||||
"oc",
|
||||
"pa-IN",
|
||||
"pl",
|
||||
"pt-BR",
|
||||
"pt-PT",
|
||||
@@ -200,10 +211,13 @@
|
||||
"sl",
|
||||
"sq",
|
||||
"sr",
|
||||
"su",
|
||||
"sv-SE",
|
||||
"th",
|
||||
"tr",
|
||||
"uk",
|
||||
"vi",
|
||||
"zgh",
|
||||
"zh-CN",
|
||||
"zh-TW"
|
||||
]
|
||||
|
||||
@@ -6,7 +6,7 @@ class TailwindExtractor {
|
||||
|
||||
const options = {
|
||||
plugins: [
|
||||
require('tailwindcss')('./tailwind.js'),
|
||||
require('tailwindcss')('./tailwind.config.js'),
|
||||
require('postcss-preset-env')
|
||||
]
|
||||
};
|
||||
|
||||
@@ -182,3 +182,4 @@ shareLinkDescription = شارِك الرابط الذي يصل إلى الملف
|
||||
shareLinkButton = شارِك الرابط
|
||||
# $name is the name of the file
|
||||
shareMessage = نزِّل ”{ $name }“ عبر { -send-brand }: خدمة لمشاركة الملفات بلا عناء وبخصوصية تامة
|
||||
learnMore = اطّلع على المزيد.
|
||||
|
||||
@@ -126,7 +126,7 @@ addPassword = পাসওয়ার্ড দ্বারা সুরক্ষ
|
||||
emailPlaceholder = আপনার ইমেইল দিন
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
signInSizeBump = সর্বোচ্চ { $size } আকারের ফাইল প্রেরণ করতে সাইন ইন করুন
|
||||
signInButton = সাইন ইন/আপ
|
||||
signInOnlyButton = সাইন ইন
|
||||
accountBenefitTitle = { -firefox } অ্যাকাউন্ট তৈরি অথবা সাইন ইন করুন
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
accountBenefitLargeFiles = সর্বোচ্চ { $size } আকারের ফাইল শেয়ার করুন
|
||||
@@ -145,3 +145,11 @@ noStreamsWarning = এই ব্রাউজার এতো বড় একট
|
||||
noStreamsOptionCopy = অন্য ব্রাউজারে খুলতে লিঙ্ক অনুলিপি করুন
|
||||
noStreamsOptionFirefox = আমাদের জনপ্রিয় ব্রাউজার ব্যবহার করুন
|
||||
noStreamsOptionDownload = এই ব্রাউজার ব্যবহার অব্যহত রাখুন
|
||||
downloadFirefoxPromo = { -send-short-brand } আপনারদের জন্য নিয়ে এসেছে একেবারে নতুন { -firefox }।
|
||||
# the next line after the colon contains a file name
|
||||
shareLinkDescription = আপনার ফাইলে লিঙ্ক শেয়ার করুন:
|
||||
shareLinkButton = লিঙ্ক শেয়ার করুন
|
||||
# $name is the name of the file
|
||||
shareMessage = { -send-brand } এর মাধ্যমে "{ $name }" ডাউনলোড করুন: সরল, নিরাপদ ফাইল শেয়ারিং
|
||||
trailheadPromo = আপনার গোপনীয়তা রক্ষা করার একটি উপায় আছে। Firefox এ যোগ দিন।
|
||||
learnMore = আরও জানুন।
|
||||
@@ -196,5 +196,5 @@ shareLinkDescription = Sdílet odkaz na soubor:
|
||||
shareLinkButton = Sdílet odkaz
|
||||
# $name is the name of the file
|
||||
shareMessage = Stáhněte si soubor „{ $name }“ s { -send-brand(case: "ins") } - jednoduché a bezpečné sdílení souborů
|
||||
trailheadPromo = Existuje snadný způsob pro ochranu vašeho soukromí. Používejte Firefox.
|
||||
trailheadPromo = Existuje způsob, jak ochránit své soukromí. Používejte Firefox.
|
||||
learnMore = Zjistit více.
|
||||
|
||||
@@ -151,3 +151,5 @@ shareLinkDescription = Del linket til din fil:
|
||||
shareLinkButton = Del link
|
||||
# $name is the name of the file
|
||||
shareMessage = Hent { $name } med { -send-brand } - simpel og sikker fildeling
|
||||
trailheadPromo = Beskyt dine digitale rettigheder. Slut dig til Firefox.
|
||||
learnMore = Læs mere.
|
||||
|
||||
@@ -151,3 +151,5 @@ shareLinkDescription = Share the link to your file:
|
||||
shareLinkButton = Share link
|
||||
# $name is the name of the file
|
||||
shareMessage = Download “{ $name }” with { -send-brand }: simple, safe file sharing
|
||||
trailheadPromo = There is a way to protect your privacy. Join Firefox.
|
||||
learnMore = Learn more.
|
||||
|
||||
@@ -126,7 +126,7 @@ addPassword = Protegido con contraseña
|
||||
emailPlaceholder = Ingresa tu correo electrónico
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
signInSizeBump = Iniciar sesión para enviar hasta { $size }
|
||||
signInButton = Iniciar sesión/registrarse
|
||||
signInOnlyButton = Iniciar sesión
|
||||
accountBenefitTitle = Crear una cuenta de { -firefox } o iniciar sesión
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
accountBenefitLargeFiles = Compartir archivos de hasta { $size }
|
||||
@@ -145,3 +145,11 @@ noStreamsWarning = Puede que este navegador no pueda descifrar un archivo tan gr
|
||||
noStreamsOptionCopy = Copiar el enlace para abrir en otro navegador
|
||||
noStreamsOptionFirefox = Prueba nuestro navegador favorito
|
||||
noStreamsOptionDownload = Continuar con este navegador
|
||||
downloadFirefoxPromo = { -send-short-brand } te lo ofrece el nuevo { -firefox }.
|
||||
# the next line after the colon contains a file name
|
||||
shareLinkDescription = Comparte el enlace a tu archivo:
|
||||
shareLinkButton = Enlace para compartir
|
||||
# $name is the name of the file
|
||||
shareMessage = Descarga «{ $name }» con { -send-brand }: es sencillo y seguro
|
||||
trailheadPromo = Existe una forma de proteger tu privacidad. Únete a Firefox.
|
||||
learnMore = Saber más.
|
||||
|
||||
@@ -23,7 +23,7 @@ fileSizeProgress = ({ $totalSize } / { $partialSize })
|
||||
sendYourFilesLink = Probatu Firefox Send
|
||||
errorPageHeader = Zerbait gaizki joan da!
|
||||
fileTooBig = Fitxategia handiegia da kargatzeko. { $size } baino txikiagoa izan behar du.
|
||||
linkExpiredAlt = Lotura iraungita
|
||||
linkExpiredAlt = Lotura iraungi da
|
||||
notSupportedHeader = Zure nabigatzailea ez da onartzen.
|
||||
notSupportedLink = Zergatik ez da nire nabigatzailea onartzen?
|
||||
notSupportedOutdatedDetail = Zoritxarrez Firefox bertsio honek ez du Firefox Send-ek behar duen web teknologia onartzen. Zure nabigatzailea eguneratu behar duzu.
|
||||
@@ -50,10 +50,34 @@ passwordSetError = Pasahitz hau ezin da ezarri
|
||||
|
||||
# Firefox Send, Send, Firefox, Mozilla are proper names and should not be localized
|
||||
-send-brand = Firefox Send
|
||||
-send-short-brand = Send
|
||||
-firefox = Firefox
|
||||
-mozilla = Mozilla
|
||||
introTitle = Partekatu fitxategiak modu sinple eta pribatuan
|
||||
introDescription = { -send-brand } tresna fitxategiak partekatzeko da, muturretik muturrera zifratuta eta automatikoki iraungitzen diren loturekin. Hortaz, partekatzen duzuna pribatua izango da eta ziur egon zaitezke zure fitxategiak ez direla online egongo betirako.
|
||||
notifyUploadEncryptDone = Zure fitxategia zifratuta eta bidaltzeko prest dago
|
||||
# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'
|
||||
archiveExpiryInfo = { $downloadCount } edo { $timespan } ondoren iraungiko da
|
||||
timespanMinutes =
|
||||
{ $num ->
|
||||
[one] minutu 1
|
||||
*[other] { $num } minutu
|
||||
}
|
||||
timespanDays =
|
||||
{ $num ->
|
||||
[one] egun 1
|
||||
*[other] { $num } egun
|
||||
}
|
||||
timespanWeeks =
|
||||
{ $num ->
|
||||
[one] aste 1
|
||||
*[other] { $num } aste
|
||||
}
|
||||
fileCount =
|
||||
{ $num ->
|
||||
[one] fitxategi 1
|
||||
*[other] { $num } fitxategi
|
||||
}
|
||||
# byte abbreviation
|
||||
bytes = B
|
||||
# kibibyte abbreviation
|
||||
@@ -64,9 +88,33 @@ mb = MB
|
||||
gb = GB
|
||||
# localized number and byte abbreviation. example "2.5MB"
|
||||
fileSize = { $num }{ $units }
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
totalSize = Tamaina guztira: { $size }
|
||||
# the next line after the colon contains a file name
|
||||
copyLinkDescription = Kopiatu fitxategia partekatzeko lotura:
|
||||
copyLinkButton = Kopiatu lotura
|
||||
downloadTitle = Deskargatu fitxategiak
|
||||
downloadDescription = { -send-brand } bidez partekatu da fitxategia muturretik muturrera zifratuta eta automatikoki iraungitzen den lotura batekin.
|
||||
trySendDescription = Probatu { -send-brand } fitxategiak partekatzeko modu sinple eta segururako.
|
||||
# count will always be > 10
|
||||
tooManyFiles =
|
||||
{ $count ->
|
||||
[one] Soilik fitxategi bakarra igo daiteke aldi berean.
|
||||
*[other] Soilik { $count } fitxategi igo daitezke aldi berean.
|
||||
}
|
||||
# count will always be > 10
|
||||
tooManyArchives =
|
||||
{ $count ->
|
||||
[one] Soilik artxibo bakarra onartzen da.
|
||||
*[other] Soilik { $count } artxibo onartzen dira.
|
||||
}
|
||||
expiredTitle = Lotura hau iraungi da.
|
||||
notSupportedDescription = { -send-brand } ez da nabigatzaile honetan ibiliko. { -send-short-brand } hobeto dabil { -firefox }(r)en azken bertsioarekin; halaber, nabigatzaile gehienen azken bertsioarekin ibiliko da.
|
||||
downloadFirefox = Deskargatu { -firefox }
|
||||
legalTitle = { -send-short-brand } pribatutasun-oharra
|
||||
legalDateStamp = 1.0 bertsioa, 2019ko martxoaren 12koa.
|
||||
# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example "2d 11h 56m"
|
||||
expiresDaysHoursMinutes = { $days }e { $hours }h { $minutes }m
|
||||
addFilesButton = Hautatu igotzeko fitxategiak
|
||||
uploadButton = Igo
|
||||
# the first part of the string 'Drag and drop files or click to send up to 1GB'
|
||||
@@ -76,8 +124,32 @@ dragAndDropFiles = Arrastatu eta jaregin fitxategiak
|
||||
orClickWithSize = edo egin klik { $size } arte igotzeko
|
||||
addPassword = Babestu pasahitzarekin
|
||||
emailPlaceholder = Idatzi zure helbide elektronikoa
|
||||
signInButton = Hasi saioa/eman izena
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
signInSizeBump = Hasi saioa { $size } arte bidaltzeko
|
||||
signInOnlyButton = Hasi saioa
|
||||
accountBenefitTitle = Sortu { -firefox } kontu bat edo hasi saioa
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
accountBenefitLargeFiles = Partekatu { $size } arteko fitxategiak
|
||||
accountBenefitDownloadCount = Partekatu fitxategiak jende gehiagorekin
|
||||
accountBenefitTimeLimit =
|
||||
{ $count ->
|
||||
[one] Utzi loturak erabilgarri egun batez
|
||||
*[other] Utzi loturak erabilgarri { $count } egunez
|
||||
}
|
||||
accountBenefitSync = Kudeatu partekatutako fitxategiak edozein gailutatik
|
||||
accountBenefitMoz = { -mozilla }ren beste zerbitzuei buruzko argibide gehiago
|
||||
signOut = Amaitu saioa
|
||||
okButton = Ados
|
||||
downloadingTitle = Deskargatzen
|
||||
noStreamsWarning = Baliteke nabigatzailea gai ez izatea horrelako tamaina handiko fitxategiak deszifratzeko.
|
||||
noStreamsOptionCopy = Kopiatu lotura beste nabigatzaile batean irekitzeko
|
||||
noStreamsOptionFirefox = Probatu gure nabigatzaile gogokoena
|
||||
noStreamsOptionDownload = Jarraitu nabigatzaile honekin
|
||||
downloadFirefoxPromo = Erabat berritutako { -firefox }(e)k eskaintzen dizu { -send-short-brand }
|
||||
# the next line after the colon contains a file name
|
||||
shareLinkDescription = Partekatu zure fitxategirako lotura:
|
||||
shareLinkButton = Partekatu lotura
|
||||
# $name is the name of the file
|
||||
shareMessage = Deskargatu "{ $name }" { -send-brand } erabiliz: fitxategi-partekatze sinple eta segurua
|
||||
trailheadPromo = Badago zure pribatutasuna babesteko modua. Egizu bat Firefoxekin.
|
||||
learnMore = Argibide gehiago.
|
||||
|
||||
@@ -1,31 +1,9 @@
|
||||
# Firefox Send is a brand name and should not be localized.
|
||||
title = Firefox Send
|
||||
siteSubtitle = آزمایش وب
|
||||
siteFeedback = بازخورد
|
||||
uploadPageHeader = اشتراکگذاری پروندهها، رمزنگاری شده و خصوصی
|
||||
uploadPageExplainer = پرونده های خود را به صورت ایمن، خصوصی و رمزنگاری شده با تعیین تاریخ انقضا خودکار ارسال کنید تا اطمینان پیدا کنید چیزهای شما همیشه آنلاین باقی نماند.
|
||||
uploadPageLearnMore = بیشتر بدانید
|
||||
uploadPageDropMessage = برای شروع بارگذاری پروندههای خود را اینجا بیاندازید
|
||||
uploadPageSizeMessage = برای بیشترین قابلیت اطمینان، بهتر است که پروندهتان کمتر از ۱ گیگابایت باشد
|
||||
uploadPageBrowseButton = یک پرونده را از روی کامپیوتر خود انتخاب کنید
|
||||
uploadPageBrowseButton1 = یک پرونده را برای بارگذاری انتخاب کنید
|
||||
uploadPageMultipleFilesAlert = بارگذاری چندین پرونده یا یک پوشه در حال حاضر پشتیبانی نمیشود.
|
||||
uploadPageBrowseButtonTitle = بارگذاری پرونده
|
||||
uploadingPageProgress = در حال بارگذاری پرونده { $filename } ({ $size })
|
||||
importingFile = در حال وارد کردن…
|
||||
verifyingFile = در حال تایید…
|
||||
encryptingFile = در حال رمزنگاری…
|
||||
decryptingFile = در حال رمزگشایی…
|
||||
notifyUploadDone = بارگذاری شما پایان یافت.
|
||||
uploadingPageMessage = به محض بارگذاری پرونده شما قادر خواهید بود برای آن گزینه انقضا تعیین کنید.
|
||||
uploadingPageCancel = لغو بارگذاری
|
||||
uploadCancelNotification = بارگذاری شما لغو شد
|
||||
uploadingPageLargeFileMessage = پرونده بزرگ است و ممکن است بارگذاری آن مدتی طول بکشد. محکم بشینید!
|
||||
uploadingFileNotification = هر وقت بارگذاری تمام شد به من اطلاع بده.
|
||||
uploadSuccessConfirmHeader = آماده برای ارسال
|
||||
uploadSvgAlt = بارگذاری
|
||||
uploadSuccessTimingHeader = پیوند به پرونده شما بعد از ۱ بار دانلود یا ۲۴ ساعت حذف خواهد شد.
|
||||
expireInfo = این پیوند به فایل شما پس از { $downloadCount } یا { $timespan } منقضی خواهد شد.
|
||||
downloadCount =
|
||||
{ $num ->
|
||||
[one] ۱ بارگیری
|
||||
@@ -36,76 +14,26 @@ timespanHours =
|
||||
[one] ۱ ساعت
|
||||
*[other] { $num } ساعت
|
||||
}
|
||||
copyUrlFormLabelWithName = برای ارسال پرونده پیوند آن را رونوشت و به اشتراک بگذارید: { $filename }
|
||||
copyUrlFormButton = رونوشت به کلیپبورد
|
||||
copiedUrl = رونوشت شد!
|
||||
deleteFileButton = حذف پرونده
|
||||
sendAnotherFileLink = ارسال پرونده دیگر
|
||||
# Alternative text used on the download link/button (indicates an action).
|
||||
downloadAltText = دریافت
|
||||
downloadsFileList = دریافتها
|
||||
# Used as header in a column indicating the amount of time left before a
|
||||
# download link expires (e.g. "10h 5m")
|
||||
timeFileList = زمان
|
||||
# Used as header in a column indicating the number of times a file has been
|
||||
# downloaded
|
||||
downloadFileName = بارگیری { $filename }
|
||||
downloadFileSize = ({ $size })
|
||||
unlockInputLabel = گذرواژه را وارد کنید
|
||||
unlockInputPlaceholder = گذرواژه
|
||||
unlockButtonLabel = باز کردن
|
||||
downloadFileTitle = دریافت پروندهٔ رمزنگاری شده
|
||||
# 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 = بارگیری
|
||||
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.
|
||||
sendYourFilesLink = Firefox Send را امتحان کنید
|
||||
downloadingPageProgress = دریافت { $filename } ({ $size })
|
||||
downloadingPageMessage = لطفا این زبانه را باز بگذارید در حالی که ما فایل شما را دریافت میکنیم و کدگذاری میکنیم.
|
||||
errorAltText = خطا در بارگذاری
|
||||
errorPageHeader = چیزی دچار اشکال شده است!
|
||||
errorPageMessage = خطایی در هنگام بارگذاری پرونده شما رخ داده است.
|
||||
errorPageLink = پرونده دیگری ارسال کنید.
|
||||
fileTooBig = این پرونده بسیار حجیم است. حجم آن میبایستی کم تر { $size } باشد.
|
||||
linkExpiredAlt = پیوند منقضی شده است
|
||||
expiredPageHeader = پیوند منقضی شده است یا در از همان ابتدا وجود نداشته است!
|
||||
notSupportedHeader = مرورگر شما پشتیبانی نمیکند.
|
||||
# Firefox Send is a brand name and should not be localized.
|
||||
notSupportedDetail = متاسفانه این مرورگر این تکنولوژی وب را که به Firefox Send قدرت میبخشد را پشتیبانی نمیکند. شما بایستی مرورگری دیگری را امتحان کنید. پیشنهاد ما به شما فایرفاکس است !
|
||||
notSupportedLink = چرا مرورگر من پشتیبانی نمیکند؟
|
||||
notSupportedOutdatedDetail = متاسفانه این نسخه از فایرفاکس این تکنولوژی وب که به Firefox Send قدرت میبخشد را پشتیبانی نمیکند. شما نیاز دارید تا مرورگر خود را بروز کنید.
|
||||
updateFirefox = بروزرسانی فایرفاکس
|
||||
downloadFirefoxButtonSub = دریافت رایگان
|
||||
uploadedFile = پرونده
|
||||
copyFileList = رونوشت از نشانی
|
||||
# expiryFileList is used as a column header
|
||||
expiryFileList = زمان انقضا
|
||||
deleteFileList = حذف
|
||||
nevermindButton = بیخیال
|
||||
legalHeader = شرایط و حریمخصوصی
|
||||
legalNoticeTestPilot = Firefox Send در حال حاضر در نسخه آزمایشی خود به صورت میدهد و تحت عنوان خلبان آموزشی <a>شرایط و خدمات</a> و <a>موارد حریم خصوصی </a> کار میکند. شما میتوانید اطلاعات بیشتر در مورد این آزمایش و اطلاعات که ذخیره میکنید را از <a> اینجا </a> کسب کنید.
|
||||
legalNoticeMozilla = استفاده از Firefox Send همچنین منصوب به موزیلا است. <a>پایگاه اینترنتی نکات حریم شخصی </a> و <a> پایگاه اطلاع رسانی شرایط خدمات و استفاده </a>.
|
||||
deletePopupText = حذف این پرونده؟
|
||||
deletePopupYes = بله
|
||||
deletePopupCancel = انصراف
|
||||
deleteButtonHover = حذف
|
||||
copyUrlHover = رونوشت از نشانی
|
||||
footerLinkLegal = ملاحظات حقوقی
|
||||
# Test Pilot is a proper name and should not be localized.
|
||||
footerLinkAbout = درباره Test Pilot
|
||||
footerLinkPrivacy = حریمخصوصی
|
||||
footerLinkTerms = شرایط
|
||||
footerLinkCookies = کوکیها
|
||||
requirePasswordCheckbox = دریافت این پرونده نیاز به گذرواژه دارد
|
||||
addPasswordButton = افزودن گذرواژه
|
||||
changePasswordButton = تغییر
|
||||
passwordTryAgain = کلمه عبور اشتباه است. مجدد تلاش کنید.
|
||||
reportIPInfringement = گزارش تخلف IP
|
||||
javascriptRequired = Firefox Send نیازمند جاوااسکریپت است
|
||||
whyJavascript = چرا Firefox Send جاوااسکریپت لازم داد؟
|
||||
enableJavascript = لطفا جاوااسکریپت را فعال کنید و مجددا تلاش کنید.
|
||||
@@ -113,9 +41,25 @@ enableJavascript = لطفا جاوااسکریپت را فعال کنید و م
|
||||
expiresHoursMinutes = { $hours }ساعت { $minutes }دقیقه
|
||||
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
|
||||
expiresMinutes = { $minutes } دقیقه
|
||||
# A short status message shown when a password is successfully set
|
||||
passwordIsSet = گذرواژه تنظیم شد
|
||||
# A short status message shown when the user enters a long password
|
||||
maxPasswordLength = حداکثر اندازهٔ گذرواژه: { $length }
|
||||
# A short status message shown when there was an error setting the password
|
||||
passwordSetError = امکان ثبت این گذواژه نیست
|
||||
|
||||
## Send version 2 strings
|
||||
|
||||
# Firefox Send, Send, Firefox, Mozilla are proper names and should not be localized
|
||||
-send-brand = Firefox Send
|
||||
-send-short-brand = ارسال
|
||||
-firefox = فایرفاکس
|
||||
-mozilla = موزیلا
|
||||
# byte abbreviation
|
||||
bytes = B
|
||||
# kibibyte abbreviation
|
||||
kb = KB
|
||||
# mebibyte abbreviation
|
||||
mb = MB
|
||||
# gibibyte abbreviation
|
||||
gb = GB
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
totalSize = حجم کل: { $size }
|
||||
|
||||
@@ -1,66 +1,158 @@
|
||||
# Firefox Send is a brand name and should not be localized.
|
||||
title = Firefox Send
|
||||
siteSubtitle = ניסוי אינטרנט
|
||||
siteFeedback = משוב
|
||||
uploadPageHeader = שיתוף קבצים פרטי, מוצפן
|
||||
uploadPageExplainer = לשלוח קבצים דרך קישור בטוח, פרטי ומוצפן שפג אוטומטית, כדי לוודא שהתכנים הפרטיים שלך לא יהיו ברשת לנצח.
|
||||
uploadPageLearnMore = מידע נוסף
|
||||
uploadPageDropMessage = יש לגרור קבצים לכאן כדי להתחיל בהעלאה
|
||||
uploadPageSizeMessage = להשגת ביצועים מיטביים, מוטב לשמור על הקובץ מתחת לגודל של 1 ג״ב
|
||||
uploadPageBrowseButton1 = נא לבחור קובץ להעלאה
|
||||
uploadPageMultipleFilesAlert = העלאה של מספר קבצים או ספריה אינה נתמכת כרגע.
|
||||
uploadPageBrowseButtonTitle = העלאת קובץ
|
||||
uploadingPageProgress = { $filename } ({ $size }) בהעלאה
|
||||
importingFile = מתבצע ייבוא...
|
||||
verifyingFile = מתבצע אימות…
|
||||
encryptingFile = מתבצעת הצפנה...
|
||||
decryptingFile = מתבצע פענוח...
|
||||
notifyUploadDone = ההעלאה שלך הסתיימה
|
||||
uploadingPageMessage = אחרי שהקובץ שלך יעלה, ניתן יהיה להגדיר אפשרויות תפוגה.
|
||||
uploadCancelNotification = ההעלאה שלך בוטלה.
|
||||
uploadingPageLargeFileMessage = קובץ זה גדול ועלול לקחת זמן להעלות אותו. סבלנות!
|
||||
uploadingFileNotification = נא להודיע לי כשתסתיים ההעלאה.
|
||||
uploadSuccessConfirmHeader = מוכן לשליחה
|
||||
uploadSvgAlt = העלאה
|
||||
uploadSuccessTimingHeader = הקישור לקובץ שלך יפוג אחרי הורדה אחת או בעוד 24 שעות.
|
||||
copyUrlFormLabelWithName = ניתן להעתיק ולשתף את הקישור כדי לשלוח את הקובץ שלך: { $filename }
|
||||
downloadCount =
|
||||
{ $num ->
|
||||
[one] הורדה אחת
|
||||
*[other] { $num } הורדות
|
||||
}
|
||||
timespanHours =
|
||||
{ $num ->
|
||||
[one] שעה אחת
|
||||
[two] שעתיים
|
||||
*[other] { $num } שעות
|
||||
}
|
||||
copiedUrl = הועתק!
|
||||
deleteFileButton = מחיקת קובץ
|
||||
sendAnotherFileLink = שליחת קובץ נוסף
|
||||
# Alternative text used on the download link/button (indicates an action).
|
||||
downloadAltText = הורדה
|
||||
# Used as header in a column indicating the number of times a file has been
|
||||
# downloaded
|
||||
downloadFileName = ההורדה נכשלה
|
||||
downloadFileSize = ({ $size })
|
||||
# Text and title used on the download link/button (indicates an action).
|
||||
unlockInputPlaceholder = ססמה
|
||||
unlockButtonLabel = שחרור נעילה
|
||||
downloadButtonLabel = הורדה
|
||||
downloadNotification = ההורדה הושלמה.
|
||||
downloadFinish = ההורדה הושלמה
|
||||
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
|
||||
fileSizeProgress = ({ $partialSize } מתוך { $totalSize })
|
||||
downloadingPageProgress = בהורדה: { $filename } ({ $size })
|
||||
errorAltText = תקלה בהעלאה
|
||||
sendYourFilesLink = נסו את Firefox Send
|
||||
errorPageHeader = משהו השתבש!
|
||||
errorPageLink = שליחת קובץ נוסף
|
||||
fileTooBig = הקובץ הזה גדול מידי להעלאה. עליו להיות קטן מ־{ $size }.
|
||||
linkExpiredAlt = הקישור פג
|
||||
notSupportedHeader = הדפדפן שלך לא נתמך.
|
||||
notSupportedLink = למה אין תמיכה בדפדפן שלי?
|
||||
downloadFirefoxButtonSub = הורדה בחינם
|
||||
uploadedFile = קובץ
|
||||
copyFileList = העתקת כתובת
|
||||
# expiryFileList is used as a column header
|
||||
expiryFileList = יפוג בעוד
|
||||
deleteFileList = מחיקה
|
||||
nevermindButton = לא משנה
|
||||
legalHeader = תנאי שירות ופרטיות
|
||||
deletePopupText = למחוק דף זה?
|
||||
deletePopupYes = כן
|
||||
notSupportedOutdatedDetail = לצערנו גרסת Firefox זו לא תומכת בטכנולוגית הרשת שמפעילה את Firefox Send. יש לעדכן את הגרסה של הדפדפן שלך.
|
||||
updateFirefox = עדכון Firefox
|
||||
deletePopupCancel = ביטול
|
||||
deleteButtonHover = מחיקה
|
||||
copyUrlHover = העתקת קישור
|
||||
footerLinkLegal = מידע משפטי
|
||||
footerLinkPrivacy = פרטיות
|
||||
footerLinkTerms = תנאי שימוש
|
||||
footerLinkCookies = קובצי עוגיות
|
||||
passwordTryAgain = סיסמה שגויה. נא לנסות שוב.
|
||||
javascriptRequired = ל־Firefox Send דרוש JavaScript
|
||||
whyJavascript = למה ל־Firefox Send דרוש JavaScript?
|
||||
enableJavascript = נא להפעיל JavaScript ולנסות שוב.
|
||||
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
|
||||
expiresHoursMinutes = { $hours } שע׳ { $minutes } דק׳
|
||||
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
|
||||
expiresMinutes = { $minutes } דק׳
|
||||
# A short status message shown when the user enters a long password
|
||||
maxPasswordLength = אורך הססמה המרבי: { $length }
|
||||
# A short status message shown when there was an error setting the password
|
||||
passwordSetError = לא ניתן להגדיר את הססמה הזאת
|
||||
|
||||
## Send version 2 strings
|
||||
|
||||
# Firefox Send, Send, Firefox, Mozilla are proper names and should not be localized
|
||||
-send-brand = Firefox Send
|
||||
-send-short-brand = Send
|
||||
-firefox = Firefox
|
||||
-mozilla = Mozilla
|
||||
introTitle = שיתוף קבצים פרטי ופשוט
|
||||
introDescription = { -send-brand } מאפשר לך לשתף קבצים עם הצפנה מקצה לקצה וקישור עם תפוגה אוטומטית. בצורה זו תוכלו לשתף קבצים באופן פרטי ולהבטיח שהדברים שלכם לא נשארים ברשת לנצח.
|
||||
notifyUploadEncryptDone = הקובץ שלך מוצפן ומוכן לשליחה
|
||||
# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'
|
||||
archiveExpiryInfo = יפוג לאחר { $downloadCount } או { $timespan }
|
||||
timespanMinutes =
|
||||
{ $num ->
|
||||
[one] דקה אחת
|
||||
*[other] { $num } דקות
|
||||
}
|
||||
timespanDays =
|
||||
{ $num ->
|
||||
[one] יום אחד
|
||||
[two] יומיים
|
||||
*[other] { $num } ימים
|
||||
}
|
||||
timespanWeeks =
|
||||
{ $num ->
|
||||
[one] שבוע אחד
|
||||
[two] שבועיים
|
||||
*[other] { $num } שבועות
|
||||
}
|
||||
fileCount =
|
||||
{ $num ->
|
||||
[one] קובץ אחד
|
||||
*[other] { $num } קבצים
|
||||
}
|
||||
# byte abbreviation
|
||||
bytes = בתים
|
||||
# kibibyte abbreviation
|
||||
kb = ק״ב
|
||||
# mebibyte abbreviation
|
||||
mb = מ״ב
|
||||
# gibibyte abbreviation
|
||||
gb = ג״ב
|
||||
# localized number and byte abbreviation. example "2.5MB"
|
||||
fileSize = { $num } { $units }
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
totalSize = גודל כולל: { $size }
|
||||
# the next line after the colon contains a file name
|
||||
copyLinkDescription = יש להעתיק את הקישור כדי לשתף את הקובץ שלך:
|
||||
copyLinkButton = העתקת קישור
|
||||
downloadTitle = הורדת קבצים
|
||||
downloadDescription = קובץ זה שותף באמצעות { -send-brand } עם הצפנה מקצה לקצה וקישור שפג באופן אוטומטי.
|
||||
trySendDescription = כדאי לנסות את { -send-brand } לשיתוף קבצים פשוט ומאובטח.
|
||||
# count will always be > 10
|
||||
tooManyFiles =
|
||||
{ $count ->
|
||||
[one] ניתן להעלות רק קובץ אחד בכל פעם.
|
||||
*[other] ניתן להעלות רק { $count } קבצים בכל פעם.
|
||||
}
|
||||
# count will always be > 10
|
||||
tooManyArchives =
|
||||
{ $count ->
|
||||
[one] רק ארכיון אחד מורשה.
|
||||
*[other] רק { $count } ארכיונים מורשים.
|
||||
}
|
||||
expiredTitle = פג תוקפו של קישור זה.
|
||||
notSupportedDescription = { -send-brand } לא יפעל עם דפדפן זה. { -send-short-brand } פועל בצורה הטובה ביותר עם הגרסה העדכנית ביותר של { -firefox }, ויעבוד עם הגרסה הנוכחית של רוב הדפדפנים.
|
||||
downloadFirefox = הורדת { -firefox }
|
||||
legalTitle = הצהרת פרטיות של { -send-short-brand }
|
||||
legalDateStamp = גרסה 1.0, בתאריך 12 במרץ 2019
|
||||
# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example "2d 11h 56m"
|
||||
expiresDaysHoursMinutes = { $days } ימים { $hours } שעות { $minutes } דקות
|
||||
addFilesButton = בחירת קבצים להעלאה
|
||||
uploadButton = העלאה
|
||||
# the first part of the string 'Drag and drop files or click to send up to 1GB'
|
||||
dragAndDropFiles = גרירה והשלכת קבצים
|
||||
# the second part of the string 'Drag and drop files or click to send up to 1GB'
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
orClickWithSize = או ללחוץ כדי לשלוח קבצים עד לגודל של { $size }
|
||||
addPassword = הגנה באמצעות ססמה
|
||||
emailPlaceholder = נא להכניס כתובת דוא״ל
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
signInSizeBump = נא להירשם כדי לשלוח קבצים עד גודל של { $size }
|
||||
signInOnlyButton = כניסה
|
||||
accountBenefitTitle = נא ליצור חשבון { -firefox } או להיכנס לחשבון
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
accountBenefitLargeFiles = שיתוף קבצים עד גודל של { $size }
|
||||
accountBenefitDownloadCount = שיתוף קבצים עם יותר אנשים
|
||||
accountBenefitTimeLimit =
|
||||
{ $count ->
|
||||
[one] שמירה על קישורים פעילים עד ליום אחד
|
||||
*[other] שמירה על קישורים פעילים עד ל־{ $count } ימים
|
||||
}
|
||||
accountBenefitSync = ניהול קבצים משותפים מכל מכשיר
|
||||
accountBenefitMoz = מידע נוסף על שירותי { -mozilla } אחרים
|
||||
signOut = יציאה
|
||||
okButton = אישור
|
||||
downloadingTitle = בהורדה
|
||||
noStreamsWarning = ייתכן שדפדפן זה לא יוכל לפענח קובץ בגודל כזה.
|
||||
noStreamsOptionCopy = העתקת הקישור לפתיחה בדפדפן אחר
|
||||
noStreamsOptionFirefox = נסו את הדפדפן המועדף עלינו
|
||||
noStreamsOptionDownload = המשך בדפדפן זה
|
||||
downloadFirefoxPromo = { -send-short-brand } מובא אליך בחסות { -firefox }
|
||||
# the next line after the colon contains a file name
|
||||
shareLinkDescription = שיתוף הקישור לקובץ שלך:
|
||||
shareLinkButton = שיתוף קישור
|
||||
# $name is the name of the file
|
||||
shareMessage = הורדת ״{ $name }״ עם { -send-brand }: שיתוף קבצים פשוט ובטוח
|
||||
trailheadPromo = ישנן דרכים נוספות להגן על הפרטיות שלכם. הצטרפו אל Firefox.
|
||||
learnMore = מידע נוסף.
|
||||
|
||||
@@ -160,3 +160,5 @@ shareLinkDescription = Dijelite poveznicu na svoju datoteku:
|
||||
shareLinkButton = Dijeli poveznicu
|
||||
# $name is the name of the file
|
||||
shareMessage = Preuzmite “{ $name }” sa { -send-brand }: jednostavno i sigurno dijeljenje datoteka
|
||||
trailheadPromo = Postoji način da zaštitite svoju privatnost. Pridružite se Firefoxu.
|
||||
learnMore = Saznajte više.
|
||||
|
||||
@@ -123,7 +123,7 @@ dragAndDropFiles = Traher e deponer files
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
orClickWithSize = o cliccar pro inviar usque { $size }
|
||||
addPassword = Proteger per contrasigno
|
||||
emailPlaceholder = Insere tu adresse email
|
||||
emailPlaceholder = Insere tu adresse de e-mail
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
signInSizeBump = Accede pro inviar usque { $size }
|
||||
signInOnlyButton = Authentica te
|
||||
|
||||
@@ -142,3 +142,5 @@ shareLinkDescription = Bagikan tautan ke berkas Anda:
|
||||
shareLinkButton = Bagikan tautan
|
||||
# $name is the name of the file
|
||||
shareMessage = Unduh "{ $name }" dengan { -send-brand }: berbagi berkas dengan sederhana dan aman
|
||||
trailheadPromo = Ada cara untuk melindungi privasi Anda. Bergabunglah dengan Firefox.
|
||||
learnMore = Pelajari lebih lanjut.
|
||||
|
||||
@@ -140,3 +140,5 @@ shareLinkDescription = ファイルへのリンクを共有しましょう:
|
||||
shareLinkButton = リンクを共有
|
||||
# $name is the name of the file
|
||||
shareMessage = { -send-brand } で "{ $name }" をダウンロード: シンプルで安全なファイル共有
|
||||
trailheadPromo = プライバシーを保護する方法があります。Firefox を試してください。
|
||||
learnMore = 詳細情報
|
||||
|
||||
@@ -54,6 +54,10 @@ passwordSetError = Awal-agi uffir ur izmir ara ad ittwabaded
|
||||
-firefox = Firefox
|
||||
-mozilla = Mozilla
|
||||
introTitle = Afessas, beṭṭu n ifuyla s wudem uslig
|
||||
introDescription = { -send-brand } ad k(yeǧǧ ad tebḍuḍ ifuyla iwgelhanensi ṭṭerf ɣer ṭṭerf akked useɣwen ara yemmten s wudem awurman. Daɣen, ad tizmireḍ ad tḥ€rzeḍ ayen i tbeṭṭuḍ s wudem uslig daɣen ad temneḍ imi agbur-ik ur yettɣimi ara srid i lebda.
|
||||
notifyUploadEncryptDone = Afaylu-ik yewgelhen daɣen ihegga i tuzna
|
||||
# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'
|
||||
archiveExpiryInfo = Ad yemmet deffir { $downloadCount } neɣ { $timespan }
|
||||
timespanMinutes =
|
||||
{ $num ->
|
||||
[one] 1 n tsedat
|
||||
@@ -90,18 +94,62 @@ totalSize = Tuɣzi s umata: { $size }
|
||||
copyLinkDescription = Nɣel aseɣwen akken ad tebḍuḍ afaylu-inek
|
||||
copyLinkButton = Nɣel aseɣwen
|
||||
downloadTitle = Sider ifuyla
|
||||
downloadDescription = Afaylu-a yettwabḍa s { -send-brand } s uwgelhen s ṭṭerf ɣer ṭṭerf s useɣwen ara yemmten s wudem awurman.
|
||||
trySendDescription = Ɛreḍ { -send-brand } i beḍḍu afessas n ifuyla s wudem ameɣtu.
|
||||
# count will always be > 10
|
||||
tooManyFiles =
|
||||
{ $count ->
|
||||
[one] Ala 1 n ufaylu i yemzren ad yali i tikkelt.
|
||||
*[other] Ala { $count } n yifuyla i yemzren ad alin i tikkelt.
|
||||
}
|
||||
# count will always be > 10
|
||||
tooManyArchives =
|
||||
{ $count ->
|
||||
[one] Ala 1 n teṛcibt i yettwasirgen.
|
||||
*[other] Ala { $count } n teṛcibin i yettwasiregn.
|
||||
}
|
||||
expiredTitle = Immut useɣwen.
|
||||
notSupportedDescription = { -send-brand } ur iteddu ara s yiminig-a. { -send-short-brand } iteddu akken iwata s lqem aneggaru n { -firefox }, daɣen iteddu s lqem amiran n tuget n yiminigen.
|
||||
downloadFirefox = Sider { -firefox }
|
||||
legalTitle = Tasertit tabaḍnit n { -send-short-brand }
|
||||
legalDateStamp = Lqem 1.0, azemz n 12 Meɣres 2019
|
||||
# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example "2d 11h 56m"
|
||||
expiresDaysHoursMinutes = { $days } ass { $hours } srg { $minutes } tsd
|
||||
addFilesButton = Fren ifuyla ad tessaliḍ
|
||||
uploadButton = Sali
|
||||
# the first part of the string 'Drag and drop files or click to send up to 1GB'
|
||||
dragAndDropFiles = Ẓuɣer sakin sers ifuyla
|
||||
# the second part of the string 'Drag and drop files or click to send up to 1GB'
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
orClickWithSize = neɣ sit akken ad tazneḍ arma d { $size }
|
||||
addPassword = Ḥrez s wawal uffir
|
||||
emailPlaceholder = Sekcem imayl inek
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
signInSizeBump = Qqen akken ad tazneḍ arma d { $size }
|
||||
signInOnlyButton = Qqen
|
||||
accountBenefitTitle = Rnu amiḍan { -firefox } akken ad teqqneḍ
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
accountBenefitLargeFiles = Bḍu ifuyla arma d { $size }
|
||||
accountBenefitDownloadCount = Bḍu ifuyla d wugan n medden
|
||||
accountBenefitTimeLimit =
|
||||
{ $count ->
|
||||
[one] Eǧǧ iseɣwan d urmiden arma d 1 n wass
|
||||
*[other] Eǧǧ iseɣwan d urmiden arma d { $count } n wassan
|
||||
}
|
||||
accountBenefitSync = Sefrek ifuyla yebdan seg yal ibenk
|
||||
accountBenefitMoz = Issin ugar ɣef yimeẓla-nniḍen n { -mozilla }
|
||||
signOut = Ffeɣ
|
||||
okButton = IH
|
||||
downloadingTitle = Azdam
|
||||
noStreamsWarning = Iminig-a ur yezmir ara ad yezmek afaylu meqqren.
|
||||
noStreamsOptionCopy = Nɣel aseɣwen i tulya deg yiminig-nniden
|
||||
noStreamsOptionFirefox = Ɛreḍ iminig-ik ufrin
|
||||
noStreamsOptionDownload = Kemmel akked iminig-a
|
||||
downloadFirefoxPromo = { -send-short-brand } yettwasumer i yal { -firefox } amaynut.
|
||||
# the next line after the colon contains a file name
|
||||
shareLinkDescription = Bḍu aseɣwen ɣer ufaylu-ik:
|
||||
shareLinkButton = Bḍu aseɣwen
|
||||
# $name is the name of the file
|
||||
shareMessage = Sider "{ $name }" s { -send-brand }: d fessas, d aɣelsan i beṭṭu n yifuyla.
|
||||
trailheadPromo = Yella wallal n ummesten n tudert-ik tusligt. Ddu ɣer Firefox.
|
||||
learnMore = Issin ugar.
|
||||
|
||||
@@ -4,7 +4,7 @@ siteFeedback = 사용자 의견
|
||||
importingFile = 가져오는 중…
|
||||
encryptingFile = 암호화 중…
|
||||
decryptingFile = 복호화 중…
|
||||
downloadCount = { $num } 다운로드
|
||||
downloadCount = 다운로드 { $num }회
|
||||
timespanHours = 1 시간
|
||||
copiedUrl = 복사 완료!
|
||||
unlockInputPlaceholder = 비밀번호
|
||||
@@ -49,7 +49,7 @@ introTitle = 간단하고, 사생활을 보호하는 파일 공유
|
||||
introDescription = { -send-brand }를 사용하면 종단 암호화와 자동으로 만료되는 링크를 사용해 파일을 공유할 수 있습니다. 안전하게 공유할 수 있고 공유된 파일이 계속 온라인에 남지 않게 됩니다.
|
||||
notifyUploadEncryptDone = 파일이 암호화 되어서 보낼 수 있게 됐습니다
|
||||
# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'
|
||||
archiveExpiryInfo = { $downloadCount }나 { $timespan } 후 만료됨
|
||||
archiveExpiryInfo = { $downloadCount } 혹은 { $timespan } 후 만료됨
|
||||
timespanMinutes =
|
||||
{ $num ->
|
||||
*[other] { $num }분
|
||||
@@ -112,7 +112,7 @@ addPassword = 비밀번호로 파일 보호
|
||||
emailPlaceholder = 이메일 입력
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
signInSizeBump = { $size }까지 파일을 보낼 수 있게 로그인
|
||||
signInButton = 로그인/등록
|
||||
signInOnlyButton = 로그인
|
||||
accountBenefitTitle = { -firefox } 계정을 하나 만들거나, 로그인
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
accountBenefitLargeFiles = { $size }까지의 파일 공유
|
||||
@@ -130,3 +130,11 @@ noStreamsWarning = 이 브라우저는 이렇게 큰 용량의 파일 암호화
|
||||
noStreamsOptionCopy = 다른 브라우저에서 열 수 있도록 링크를 복사
|
||||
noStreamsOptionFirefox = 우리가 애용하는 브라우저를 사용해 보세요
|
||||
noStreamsOptionDownload = 이 브라우저로 계속하기
|
||||
downloadFirefoxPromo = 완전히 새로운 { -firefox }로 { -send-short-brand }가 제공됩니다.
|
||||
# the next line after the colon contains a file name
|
||||
shareLinkDescription = 파일 링크 공유:
|
||||
shareLinkButton = 링크 공유
|
||||
# $name is the name of the file
|
||||
shareMessage = { -send-brand }으로 “{ $name }” 파일을 내려받으세요: 쉽고 안전한 파일 공유입니다.
|
||||
trailheadPromo = 개인 정보를 보호하는 방법이 있습니다. 파이어폭스와 함께 하세요.
|
||||
learnMore = 자세히 알아보기
|
||||
|
||||
@@ -168,3 +168,5 @@ shareLinkDescription = Pasidalinkite saitu į jūsų failą:
|
||||
shareLinkButton = Dalintis saitu
|
||||
# $name is the name of the file
|
||||
shareMessage = Atsisiųskite „{ $name }“ su „{ -send-brand }“: paprastas, saugus dalinimasis failais
|
||||
trailheadPromo = Yra būdas apsaugoti jūsų privatumą. Naudokite „Firefox“.
|
||||
learnMore = Sužinoti daugiau.
|
||||
|
||||
@@ -54,6 +54,7 @@ passwordSetError = Dette passordet kunne ikke settes
|
||||
-firefox = Firefox
|
||||
-mozilla = Mozilla
|
||||
introTitle = Enkel, privat fildeling
|
||||
introDescription = { -send-brand } lar deg dele filer via en tidsbegrenset lenke med ende-til-ende-kryptering. På den måten kan du dele filer privat og samtidig være trygg på at filene dine ikke blir liggende på nettet for alltid.
|
||||
notifyUploadEncryptDone = Filen din er kryptert og klar til å sende
|
||||
# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'
|
||||
archiveExpiryInfo = Utløper etter { $downloadCount } eller { $timespan }
|
||||
@@ -77,9 +78,78 @@ fileCount =
|
||||
[one] 1 fil
|
||||
*[other] { $num } filer
|
||||
}
|
||||
# size is a localized number followed by a unit of bytes, ex. 2.5GB
|
||||
# byte abbreviation
|
||||
bytes = B
|
||||
# kibibyte abbreviation
|
||||
kb = KB
|
||||
# mebibyte abbreviation
|
||||
mb = MB
|
||||
# gibibyte abbreviation
|
||||
gb = GB
|
||||
# localized number and byte abbreviation. example "2.5MB"
|
||||
fileSize = { $num }{ $units }
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
totalSize = Total størrelse: { $size }
|
||||
# the next line after the colon contains a file name
|
||||
copyLinkDescription = Kopier lenken for å dele filen din:
|
||||
copyLinkButton = Kopier lenke
|
||||
downloadTitle = Last ned filer
|
||||
downloadDescription = Denne filen ble delt via { -send-brand } med ende-til-ende-kryptering og en lenke som automatisk utløper.
|
||||
trySendDescription = Prøv { -send-brand } for enkel, sikker fildeling.
|
||||
# count will always be > 10
|
||||
tooManyFiles =
|
||||
{ $count ->
|
||||
[one] Kun 1 fil kan lastes opp om gangen.
|
||||
*[other] Kun { $count } filer kan lastes opp om gangen.
|
||||
}
|
||||
# count will always be > 10
|
||||
tooManyArchives =
|
||||
{ $count ->
|
||||
[one] Kun 1 arkiv er tillatt.
|
||||
*[other] Kun { $count } arkiver er tillatt.
|
||||
}
|
||||
expiredTitle = Denne lenken er utløpt.
|
||||
notSupportedDescription = { -send-brand } virker ikke med denne nettleseren. { -send-short-brand } fungerer best med den nyeste versjonen av { -firefox }, og vil fungere med den nyeste versjonen av de fleste nettlesere.
|
||||
downloadFirefox = Last ned { -firefox }
|
||||
legalTitle = { -send-short-brand } Personvernerklæring
|
||||
legalDateStamp = Versjon 1.0, datert den 12. mars 2019
|
||||
# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example "2d 11h 56m"
|
||||
expiresDaysHoursMinutes = { $days }d { $hours }t { $minutes }m
|
||||
addFilesButton = Velg filer du vil laste opp
|
||||
uploadButton = Last opp
|
||||
# the first part of the string 'Drag and drop files or click to send up to 1GB'
|
||||
dragAndDropFiles = Dra og slipp filer
|
||||
# the second part of the string 'Drag and drop files or click to send up to 1GB'
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
orClickWithSize = eller klikk for å sende filer på opptil { $size }
|
||||
addPassword = Beskytt med passord
|
||||
emailPlaceholder = Skriv inn e-postadressen din
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
signInSizeBump = Logg inn for å sende opptil { $size }
|
||||
signInOnlyButton = Logg inn
|
||||
accountBenefitTitle = Opprett en { -firefox }-konto eller logg inn
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
accountBenefitLargeFiles = Del filer på opptil { $size }
|
||||
accountBenefitDownloadCount = Del filer med flere personer
|
||||
accountBenefitTimeLimit =
|
||||
{ $count ->
|
||||
[one] Hold lenker aktiv opptil 1 dag
|
||||
*[other] Hold lenker aktiv opptil { $count } dager
|
||||
}
|
||||
accountBenefitSync = Behandle delte filer fra en hvilken som helst enhet
|
||||
accountBenefitMoz = Les om andre { -mozilla }-tjenester
|
||||
signOut = Logg ut
|
||||
okButton = OK
|
||||
downloadingTitle = Laster ned
|
||||
noStreamsWarning = Denne nettleseren kan kanskje ikke dekryptere en så stor fil.
|
||||
noStreamsOptionCopy = Kopier lenken for å åpne den i en annen nettleser
|
||||
noStreamsOptionFirefox = Prøv favorittnettleseren vår
|
||||
noStreamsOptionDownload = Fortsett med denne nettleseren
|
||||
downloadFirefoxPromo = { -send-short-brand } presenteres for deg av den helt nye { -firefox }.
|
||||
# the next line after the colon contains a file name
|
||||
shareLinkDescription = Del lenken til filen din:
|
||||
shareLinkButton = Del lenke
|
||||
# $name is the name of the file
|
||||
shareMessage = Last ned ‹{ $name }› med { -send-brand }: enkel, trygg fildeling
|
||||
trailheadPromo = Det finnes en måte å ta vare på personvernet ditt. Bruk Firefox.
|
||||
learnMore = Les mer.
|
||||
|
||||
155
public/locales/oc/send.ftl
Normal file
155
public/locales/oc/send.ftl
Normal file
@@ -0,0 +1,155 @@
|
||||
# Firefox Send is a brand name and should not be localized.
|
||||
title = Firefox Send
|
||||
siteFeedback = Comentaris
|
||||
importingFile = Importacion…
|
||||
encryptingFile = Chiframent…
|
||||
decryptingFile = Deschiframent…
|
||||
downloadCount =
|
||||
{ $num ->
|
||||
[one] 1 telecargament
|
||||
*[other] { $num } telecargaments
|
||||
}
|
||||
timespanHours =
|
||||
{ $num ->
|
||||
[one] 1 ora
|
||||
*[other] { $num } oras
|
||||
}
|
||||
copiedUrl = Copiat !
|
||||
unlockInputPlaceholder = Senhal
|
||||
unlockButtonLabel = Desverrolhar
|
||||
downloadButtonLabel = Telecargar
|
||||
downloadFinish = Telecargament acabat
|
||||
fileSizeProgress = ({ $partialSize } sus { $totalSize })
|
||||
sendYourFilesLink = Ensajar Firefox Send
|
||||
errorPageHeader = I a quicòm que truca.
|
||||
fileTooBig = Aqueste fichièr es tròp gròs per l’enviar. Sa talha deu èsser inferiora a { $size }.
|
||||
linkExpiredAlt = Lo ligam a expirat
|
||||
notSupportedHeader = Vòstre navegador es pas compatible.
|
||||
notSupportedLink = Perqué mon navegador es pas compatible ?
|
||||
notSupportedOutdatedDetail = Aquesta version de Firefox es pas compatibla amb la tecnologia web amb la quala fonciona Firefox Send. Vos cal metre a jorn lo navegador.
|
||||
updateFirefox = Metre a jorn Firefox
|
||||
deletePopupCancel = Anullar
|
||||
deleteButtonHover = Suprimir
|
||||
footerLinkLegal = Mencions legalas
|
||||
footerLinkPrivacy = Vida privada
|
||||
footerLinkCookies = Cookies
|
||||
passwordTryAgain = Senhal incorrècte. Tornatz ensajar.
|
||||
javascriptRequired = Firefox Send requesís JavaScript
|
||||
whyJavascript = Perque Firefox Send requesís JavaScript ?
|
||||
enableJavascript = Volgatz activar lo JavaScript e ensajatz tornamai.
|
||||
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
|
||||
expiresHoursMinutes = { $hours } h { $minutes } min
|
||||
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
|
||||
expiresMinutes = { $minutes } min
|
||||
# A short status message shown when the user enters a long password
|
||||
maxPasswordLength = Talha maximala del senhal : { $length }
|
||||
# A short status message shown when there was an error setting the password
|
||||
passwordSetError = Aqueste senhal a pas pogut èsser definit
|
||||
|
||||
## Send version 2 strings
|
||||
|
||||
# Firefox Send, Send, Firefox, Mozilla are proper names and should not be localized
|
||||
-send-brand = Firefox Send
|
||||
-send-short-brand = Send
|
||||
-firefox = Firefox
|
||||
-mozilla = Mozilla
|
||||
introTitle = Partatge simple e privat de fichièrs
|
||||
introDescription = { -send-brand } vos permet de partejar de fichièr amb un chiframent del cap a la fin e un ligam qu’expira automaticament. Atal podètz gardar privat çò que partejatz e vos assegurar que demorarà pas en linha per totjorn.
|
||||
notifyUploadEncryptDone = Vòstre fichièr es chifrat e prèst per mandadís
|
||||
# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'
|
||||
archiveExpiryInfo = Expira aprèp { $downloadCount } o { $timespan }
|
||||
timespanMinutes =
|
||||
{ $num ->
|
||||
[one] 1 minuta
|
||||
*[other] { $num } minutas
|
||||
}
|
||||
timespanDays =
|
||||
{ $num ->
|
||||
[one] 1 jorn
|
||||
*[other] { $num } jorns
|
||||
}
|
||||
timespanWeeks =
|
||||
{ $num ->
|
||||
[one] 1 setmana
|
||||
*[other] { $num } setmanas
|
||||
}
|
||||
fileCount =
|
||||
{ $num ->
|
||||
[one] 1 fichièr
|
||||
*[other] { $num } fichièrs
|
||||
}
|
||||
# byte abbreviation
|
||||
bytes = o
|
||||
# kibibyte abbreviation
|
||||
kb = Ko
|
||||
# mebibyte abbreviation
|
||||
mb = Mo
|
||||
# gibibyte abbreviation
|
||||
gb = Go
|
||||
# localized number and byte abbreviation. example "2.5MB"
|
||||
fileSize = { $num } { $units }
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
totalSize = Talha totala : { $size }
|
||||
# the next line after the colon contains a file name
|
||||
copyLinkDescription = Copiatz lo ligam per partejar vòstre fichièr :
|
||||
copyLinkButton = Copiar lo ligam
|
||||
downloadTitle = Telecargar los fichièrs
|
||||
downloadDescription = Aqueste fichièr foguèt partejat via { -send-brand } amb chiframent del cap a la fin e un ligam qu’expira automaticament.
|
||||
trySendDescription = Ensajatz { -send-brand } per un partiment de fichièrs simple e segur.
|
||||
# count will always be > 10
|
||||
tooManyFiles =
|
||||
{ $count ->
|
||||
[one] Òm pòt pas qu’enviar 1 fichièr al còp.
|
||||
*[other] Òm pòt pas qu’enviar { $count } fichièrs al còp.
|
||||
}
|
||||
# count will always be > 10
|
||||
tooManyArchives =
|
||||
{ $count ->
|
||||
[one] Pas qu’un archiu es autorizat.
|
||||
*[other] Pas que { $count } archius son autorizats.
|
||||
}
|
||||
expiredTitle = Aqueste ligam a expirat.
|
||||
notSupportedDescription = { -send-brand } foncionarà pas amb aqueste navegador. { -send-short-brand } fonciona melhor amb la darrièra version de { -firefox } e foncionarà amb la version mai recenta de la màger part dels navegadors.
|
||||
downloadFirefox = Telecargar { -firefox }
|
||||
legalTitle = Avís de confidencialitat de { -send-short-brand }
|
||||
legalDateStamp = Version 1.0 del 12 de març de 2019
|
||||
# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example "2d 11h 56m"
|
||||
expiresDaysHoursMinutes = { $days } j { $hours } h { $minutes } min
|
||||
addFilesButton = Seleccionatz los fichièrs de mandar
|
||||
uploadButton = Enviar
|
||||
# the first part of the string 'Drag and drop files or click to send up to 1GB'
|
||||
dragAndDropFiles = Lissatz-depausatz de fichièrs
|
||||
# the second part of the string 'Drag and drop files or click to send up to 1GB'
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
orClickWithSize = o clicatz per enviar fins a { $size }
|
||||
addPassword = Protegir amb un senhal
|
||||
emailPlaceholder = Picatz vòstra adreça electronica
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
signInSizeBump = Connectatz-vos per enviar fins a { $size }
|
||||
signInOnlyButton = Connexion
|
||||
accountBenefitTitle = Creatz un compte { -firefox } o connectatz-vos
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
accountBenefitLargeFiles = Partejatz de fichièrs fins a { $size }
|
||||
accountBenefitDownloadCount = Partejatz de fichièrs amb mai de personas
|
||||
accountBenefitTimeLimit =
|
||||
{ $count ->
|
||||
[one] Mantenètz los ligams actius fins a 1 jorn
|
||||
*[other] Mantenètz los ligams actius fins a { $count } jorns
|
||||
}
|
||||
accountBenefitSync = Gerissètz los fichièrs partejats de qualque siá periferic estant
|
||||
accountBenefitMoz = Aprenètz-ne mai suls autres servicis { -mozilla }
|
||||
signOut = Desconnexion
|
||||
okButton = D'acòrd
|
||||
downloadingTitle = Telecargament
|
||||
noStreamsWarning = Pòt arribar qu’aqueste navegador pòsca pas deschifrar un fichièr tan gròs.
|
||||
noStreamsOptionCopy = Copiatz lo ligam per lo dobrir dins un autre navegador
|
||||
noStreamsOptionFirefox = Ensajatz nòstre navegador preferit
|
||||
noStreamsOptionDownload = Contunhar amb aqueste navegador
|
||||
downloadFirefoxPromo = Lo nòu { -firefox } vos provesís { -send-short-brand }.
|
||||
# the next line after the colon contains a file name
|
||||
shareLinkDescription = Partejatz lo ligam cap a vòstre fichièr :
|
||||
shareLinkButton = Partejar lo ligam
|
||||
# $name is the name of the file
|
||||
shareMessage = Telecargar « { $name } » amb { -send-brand } : un biais simple e segur de partejar de fichièrs.
|
||||
trailheadPromo = Existís un biais de protegir vòstra vida privada. Rejonhètz Firefox.
|
||||
learnMore = Ne saber mai.
|
||||
@@ -151,3 +151,5 @@ shareLinkDescription = ਆਪਣੀ ਫਾਇਲ ਲਈ ਲਿੰਕ ਸਾਂ
|
||||
shareLinkButton = ਲਿੰਕ ਸਾਂਝਾ ਕਰੋ
|
||||
# $name is the name of the file
|
||||
shareMessage = { -send-brand } ਨਾਲ "{ $name }" ਡਾਊਨਲੋਡ ਕਰੋ: ਸੌਖਾ, ਸੁਰੱਖਿਅਤ ਫਾਇਲ ਸਾਂਝਾ ਕਰਨਾ
|
||||
trailheadPromo = ਤੁਹਾਡੀ ਪਰਦੇਦਾਰੀ ਦੀ ਸੁਰੱਖਿਆ ਦਾ ਢੰਗ ਹੈ। ਫਾਇਰਫਾਕਸ ਨਾਲ ਜੁੜੋ।
|
||||
learnMore = ਹੋਰ ਸਿੱਖੋ
|
||||
|
||||
@@ -54,7 +54,7 @@ passwordSetError = Essa senha não pôde ser definida
|
||||
-firefox = Firefox
|
||||
-mozilla = Mozilla
|
||||
introTitle = Compartilhamento de arquivos fácil e privativo
|
||||
introDescription = O { -send-brand } permite compartilhar arquivos com criptografia ponto a ponto e um link que expira automaticamente. Assim você pode manter o que compartilha privativo e ter certeza que suas coisas não ficarão online para sempre.
|
||||
introDescription = O { -send-brand } permite compartilhar arquivos com criptografia de ponta a ponta e um link que expira automaticamente. Assim você pode manter o que compartilha privativo e ter certeza que suas coisas não ficarão online para sempre.
|
||||
notifyUploadEncryptDone = Seu arquivo foi criptografado e está pronto para ser enviado
|
||||
# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'
|
||||
archiveExpiryInfo = Expirar após { $downloadCount } ou { $timespan }
|
||||
@@ -94,7 +94,7 @@ totalSize = Tamanho total: { $size }
|
||||
copyLinkDescription = Copie o link para compartilhar seu arquivo:
|
||||
copyLinkButton = Copiar link
|
||||
downloadTitle = Baixar arquivos
|
||||
downloadDescription = Este arquivo foi compartilhado via { -send-brand } com criptografia ponto a ponto e um link que expira automaticamente.
|
||||
downloadDescription = Este arquivo foi compartilhado via { -send-brand } com criptografia de ponta a ponta e um link que expira automaticamente.
|
||||
trySendDescription = Experimente o { -send-brand } para compartilhamento de arquivos simples e seguro.
|
||||
# count will always be > 10
|
||||
tooManyFiles =
|
||||
@@ -143,7 +143,7 @@ okButton = OK
|
||||
downloadingTitle = Baixando
|
||||
noStreamsWarning = Este navegador pode não conseguir descriptografar um arquivo tão grande.
|
||||
noStreamsOptionCopy = Copiar o link para abrir em outro navegador
|
||||
noStreamsOptionFirefox = Experimentar nosso navegador preferido
|
||||
noStreamsOptionFirefox = Experimente nosso navegador preferido
|
||||
noStreamsOptionDownload = Continuar com este navegador
|
||||
downloadFirefoxPromo = O { -send-short-brand } é apresentado pelo novo { -firefox }.
|
||||
# the next line after the colon contains a file name
|
||||
@@ -151,5 +151,5 @@ shareLinkDescription = Compartilhe o link para o seu arquivo:
|
||||
shareLinkButton = Compartilhar link
|
||||
# $name is the name of the file
|
||||
shareMessage = Baixe "{ $name }" com o { -send-brand }: compartilhamento de arquivos simples e seguro
|
||||
trailheadPromo = Existe um meio de proteger sua privacidade. Cadastre-se no Firefox.
|
||||
trailheadPromo = Existe um meio de proteger sua privacidade. Use o Firefox.
|
||||
learnMore = Saiba mais.
|
||||
|
||||
@@ -23,7 +23,7 @@ downloadButtonLabel = Descarcă
|
||||
downloadFinish = Descărcare încheiată
|
||||
fileSizeProgress = ({ $partialSize } din { $totalSize })
|
||||
sendYourFilesLink = Încearcă Firefox Send
|
||||
errorPageHeader = Ceva a mers prost!
|
||||
errorPageHeader = Ceva nu a funcționat!
|
||||
fileTooBig = Acest fișier este prea mare. Ar trebuie să fie sub { $size }.
|
||||
linkExpiredAlt = Link expirat
|
||||
notSupportedHeader = Browserul tău nu este suportat.
|
||||
@@ -35,7 +35,7 @@ deleteButtonHover = Șterge
|
||||
footerLinkLegal = Mențiuni legale
|
||||
footerLinkPrivacy = Confidențialitate
|
||||
footerLinkCookies = Cookie-uri
|
||||
passwordTryAgain = Parola este incorectă. Încearcă din nou.
|
||||
passwordTryAgain = Parolă incorectă. Încearcă din nou.
|
||||
javascriptRequired = Firefox Send necesită JavaScript
|
||||
whyJavascript = De ce Firefox Send necesită JavaScript?
|
||||
enableJavascript = Te rugăm să reactivezi JavaScript și să încerci din nou.
|
||||
@@ -56,7 +56,7 @@ passwordSetError = Această parolă nu a putut fi setată
|
||||
-firefox = Firefox
|
||||
-mozilla = Mozilla
|
||||
introTitle = Partajare de fișiere simplă și privată
|
||||
introDescription = { -send-brand } îți permite să partajezi fișiere cu criptare end-to-end și un link care expiră automat. Deci, poți păstra confidențial ceea ce partajezi și te poți asigura că ce ai partajat nu rămâne online pentru totdeauna.
|
||||
introDescription = { -send-brand } îți permite să partajezi fișiere cu criptare capăt-la-capăt și un link care expiră automat. Deci, poți păstra confidențial ceea ce partajezi și te poți asigura că ce ai partajat nu rămâne online pentru totdeauna.
|
||||
notifyUploadEncryptDone = Fișierul tău este criptat și gata de trimitere
|
||||
# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'
|
||||
archiveExpiryInfo = Expiră după { $downloadCount } sau { $timespan }
|
||||
@@ -100,8 +100,8 @@ totalSize = Mărime totală: { $size }
|
||||
copyLinkDescription = Copiază linkul pentru partajarea fișierului:
|
||||
copyLinkButton = Copiază linkul
|
||||
downloadTitle = Descarcă fișierele
|
||||
downloadDescription = Acest fișier a fost partajat prin { -send-brand }, cu criptare end-to-end și un link ce expiră automat.
|
||||
trySendDescription = Încearcă { -send-brand } pentru o partajare de fișiere simplă și sigură.
|
||||
downloadDescription = Acest fișier a fost partajat prin { -send-brand }, cu criptare capăt-la-capăt și un link care expiră automat.
|
||||
trySendDescription = Încearcă { -send-brand } pentru o partajare simplă și sigură a fișierelor.
|
||||
# count will always be > 10
|
||||
tooManyFiles =
|
||||
{ $count ->
|
||||
@@ -133,7 +133,7 @@ orClickWithSize = sau dă clic pentru a trimite până la { $size }
|
||||
addPassword = Protejează cu parolă
|
||||
emailPlaceholder = Introdu e-mailul tău
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
signInSizeBump = Autentifică-te ca să trimiți până la { $size }
|
||||
signInSizeBump = Autentifică-te pentru a trimite până la { $size }
|
||||
signInOnlyButton = Autentificare
|
||||
accountBenefitTitle = Creează un cont { -firefox } sau autentifică-te
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
@@ -160,5 +160,5 @@ shareLinkDescription = Partajează linkul către fișier:
|
||||
shareLinkButton = Partajează linkul
|
||||
# $name is the name of the file
|
||||
shareMessage = Descarcă „{ $name }” cu { -send-brand }: partajare simplă și sigură a fișierelor
|
||||
trailheadPromo = Există o modalitate de a-ți proteja confidențialitatea. Alătură-te Firefox.
|
||||
trailheadPromo = Există o modalitate de a-ți proteja viața privată. Alătură-te Firefox.
|
||||
learnMore = Află mai multe.
|
||||
|
||||
@@ -24,7 +24,7 @@ downloadFinish = Загрузка завершена
|
||||
fileSizeProgress = ({ $partialSize } из { $totalSize })
|
||||
sendYourFilesLink = Попробовать Firefox Send
|
||||
errorPageHeader = Что-то пошло не так!
|
||||
fileTooBig = Этот файл слишком большой для загрузки. Он должен быть меньше { $size }.
|
||||
fileTooBig = Файл слишком большой. Он должен быть меньше { $size }.
|
||||
linkExpiredAlt = Истёк срок действия ссылки
|
||||
notSupportedHeader = Ваш браузер не поддерживается.
|
||||
notSupportedLink = Почему мой браузер не поддерживается?
|
||||
@@ -160,3 +160,5 @@ shareLinkDescription = Поделитесь ссылкой на ваш файл:
|
||||
shareLinkButton = Поделиться ссылкой
|
||||
# $name is the name of the file
|
||||
shareMessage = Загрузите «{ $name }» с { -send-brand }: простой и безопасный обмен файлами
|
||||
trailheadPromo = Существует способ защитить вашу приватность. Присоединяйтесь к Firefox.
|
||||
learnMore = Подробнее.
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
# Firefox Send is a brand name and should not be localized.
|
||||
title = Firefox Send
|
||||
siteFeedback = Zvirikutaurwa
|
||||
uploadPageLearnMore = Dzidza zvimwe
|
||||
# Used as header in a column indicating the amount of time left before a
|
||||
# download link expires (e.g. "10h 5m")
|
||||
timeFileList = Nguva
|
||||
deletePopupYes = Hongu
|
||||
changePasswordButton = Shandura
|
||||
importingFile = Kutora faira
|
||||
encryptingFile = Kuinikiriputa
|
||||
enableJavascript = Ndinokumbira mubvumidze JavaScript moedza zvekare
|
||||
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
|
||||
expiresHoursMinutes = { $hours }maawa { $minutes }mineti
|
||||
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
|
||||
expiresMinutes = { $minutes }mineti
|
||||
# A short status message shown when a password is successfully set
|
||||
passwordIsSet = Pasiwedhi yaita
|
||||
# A short status message shown when the user enters a long password
|
||||
maxPasswordLength = Pasiwedhi haipfuuri mavara:{ $length }
|
||||
# A short status message shown when there was an error setting the password
|
||||
passwordSetError = Pasiwedhi haina kuita
|
||||
|
||||
## Send version 2 strings
|
||||
|
||||
|
||||
@@ -151,3 +151,5 @@ shareLinkDescription = Ndani me të tjerët lidhjen për te kartela juaj:
|
||||
shareLinkButton = Ndani me të tjerët lidhjen
|
||||
# $name is the name of the file
|
||||
shareMessage = Shkarkojeni “{ $name }” me { -send-brand }: shkëmbim kartelash dhe thjesht dhe pa rrezik
|
||||
trailheadPromo = Ka një rrugë për të mbrojtur privatësinë tuaj. Bëhuni pjesë e Firefox-it.
|
||||
learnMore = Mësoni më tepër.
|
||||
|
||||
@@ -134,7 +134,7 @@ addPassword = Заштитите лозинком
|
||||
emailPlaceholder = Унесите вашу е-адресу
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
signInSizeBump = Пријавите се да пошаљете садржај до { $size }
|
||||
signInButton = Пријава/регистрација
|
||||
signInOnlyButton = Пријавите се
|
||||
accountBenefitTitle = Направите { -firefox } налог или се пријавите
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
accountBenefitLargeFiles = Поделите датотеке велике до { $size }
|
||||
@@ -154,3 +154,11 @@ noStreamsWarning = Овај прегледач можда неће моћи да
|
||||
noStreamsOptionCopy = Копирај везу за отварање у другом прегледачу
|
||||
noStreamsOptionFirefox = Пробајте наш омиљени прегледач
|
||||
noStreamsOptionDownload = Наставите у овом прегледачу
|
||||
downloadFirefoxPromo = { -send-short-brand } вам је омогућен захваљући потпуно новом програму { -firefox }.
|
||||
# the next line after the colon contains a file name
|
||||
shareLinkDescription = Поделите везу до датотеке:
|
||||
shareLinkButton = Поделите везу
|
||||
# $name is the name of the file
|
||||
shareMessage = Преузмите „{ $name }“ помоћу програма { -send-brand }: једноставно и безбедно дељење датотека
|
||||
trailheadPromo = Постоји начин да заштитите вашу приватност. Придружите се Firefox-у.
|
||||
learnMore = Сазнајте више.
|
||||
|
||||
@@ -30,7 +30,7 @@ deletePopupCancel = Bolay
|
||||
deleteButtonHover = Pupus
|
||||
footerLinkLegal = Légal
|
||||
footerLinkPrivacy = Privasi
|
||||
footerLinkCookies = Kuki
|
||||
footerLinkCookies = Réréméh
|
||||
passwordTryAgain = Kecap sandi salah. Pecakan deui.
|
||||
javascriptRequired = Firefox Send merlukeun JavaScript
|
||||
whyJavascript = Naha Firefox Send merlukeun JavaScript?
|
||||
|
||||
@@ -1,29 +1,9 @@
|
||||
# Firefox Send is a brand name and should not be localized.
|
||||
title = Firefox Send
|
||||
siteSubtitle = జాల ప్రయోగం
|
||||
siteFeedback = అభిప్రాయం
|
||||
uploadPageLearnMore = ఇంకా తెలుసుకోండి
|
||||
uploadPageDropMessage = ఎగుమతిని ప్రారంభించడానికి మీ ఫైలును ఇక్కడ విడిచిపెట్టండి
|
||||
uploadPageSizeMessage = అత్యంత నమ్మకమైన కార్యం కోసం, మీ ఫైలును 1GB కంటే తక్కువగా ఉంచడం ఉత్తమం
|
||||
uploadPageBrowseButton = మీ కంప్యూటర్లో ఒక ఫైలును ఎంచుకోండి
|
||||
uploadPageBrowseButton1 = ఎక్కించటానికి ఒక ఫైలును ఎంచుకోండి
|
||||
uploadPageMultipleFilesAlert = పలు ఫైళ్ళను లేదా సంయచాన్ని ఎక్కించడానికి ప్రస్తుతం తోడ్పాటు లేదు.
|
||||
uploadPageBrowseButtonTitle = ఫైలును ఎగుమతి చేయండి
|
||||
uploadingPageProgress = { $filename } ({ $size }) ఎక్కుతోంది
|
||||
importingFile = దిగుమతవుతోంది...
|
||||
verifyingFile = పరిశీలిస్తున్నది…
|
||||
encryptingFile = గుప్తీకరిస్తోంది...
|
||||
decryptingFile = వ్యక్తపరుస్తోంది...
|
||||
notifyUploadDone = మీ ఎగుమతి పూర్తయింది.
|
||||
uploadingPageMessage = మీ ఫైలును మీరు ఎగుమతి చేసిన తర్వాత గడువు ఎంపికలను సరిగా ఏర్పాటు చేయగలరు.
|
||||
uploadingPageCancel = ఎగుమతి రద్దు చేయండి
|
||||
uploadCancelNotification = మీ ఎగుమతి రద్దు చేయబడింది.
|
||||
uploadingPageLargeFileMessage = ఈ ఫైలు పెద్దగా ఉంది అందువలన ఎగుమతి చేయడానికి కొంత సమయం పట్టవచ్చు. వేచి ఉండండి!
|
||||
uploadingFileNotification = ఎగుమతి పూర్తయినప్పుడు నాకు తెలియచేయండి.
|
||||
uploadSuccessConfirmHeader = పంపించడానికి సిద్ధంగా ఉంది
|
||||
uploadSvgAlt = ఎగుమతి చేయండి
|
||||
uploadSuccessTimingHeader = మీ ఫైలు లంకె గడువు 1 దిగుమతి తరువాత లేదా 24 గంటల తరువాత ముగుస్తుంది.
|
||||
expireInfo = మీ ఫైలుకు లంకె { $downloadCount } లేదా { $timespan } తర్వాత గడువు అవుతుంది.
|
||||
downloadCount =
|
||||
{ $num ->
|
||||
[one] 1 దింపుకోలు
|
||||
@@ -34,68 +14,26 @@ timespanHours =
|
||||
[one] 1 గంట
|
||||
*[other] { $num } గంటలు
|
||||
}
|
||||
copyUrlFormLabelWithName = మీ ఫైల్ను పంపడానికి లంకెను నకలు చేయండి మరియు పంచండి: { $filename }
|
||||
copyUrlFormButton = క్లిప్బోర్డ్కు నకలు చేయండి
|
||||
copiedUrl = నకలు చేయబడింది!
|
||||
deleteFileButton = ఫైలును తొలగించండి
|
||||
sendAnotherFileLink = మరో ఫైలును పంపండి
|
||||
# Alternative text used on the download link/button (indicates an action).
|
||||
downloadAltText = దిగుమతి
|
||||
downloadsFileList = దింపుకోళ్ళు
|
||||
# Used as header in a column indicating the amount of time left before a
|
||||
# download link expires (e.g. "10h 5m")
|
||||
timeFileList = సమయం
|
||||
# Used as header in a column indicating the number of times a file has been
|
||||
# downloaded
|
||||
downloadFileName = దిగుమతి { $filename }
|
||||
downloadFileSize = ({ $size })
|
||||
unlockInputLabel = సంకేతపదాన్ని తెలపండి
|
||||
unlockInputPlaceholder = సంకేతపదం
|
||||
unlockButtonLabel = తాళం తీయి
|
||||
# Text and title used on the download link/button (indicates an action).
|
||||
downloadButtonLabel = దిగుమతి
|
||||
downloadNotification = మీ దిగుమతి పూర్తయ్యింది.
|
||||
downloadFinish = దిగుమతి పూర్తయింది
|
||||
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
|
||||
fileSizeProgress = { $totalSize }) యొక్క ({ $partialSize }
|
||||
# Firefox Send is a brand name and should not be localized.
|
||||
sendYourFilesLink = Firefox sendను ప్రయత్నించండి
|
||||
downloadingPageProgress = దిగుమతిచేస్తున్నది { $filename } ({ $size })
|
||||
errorAltText = ఎగుమతిలో లోపం
|
||||
errorPageHeader = ఏదో తప్పిదం జరిగింది!
|
||||
errorPageMessage = ఫైల్ను ఎగుమతి చేయడంలో లోపం ఉంది.
|
||||
errorPageLink = మరో ఫైలును పంపండి
|
||||
fileTooBig = ఆ ఫైలు ఎక్కించడానికి చాలా పెద్దగా ఉంది. ఫైళ్ళు { $size } కంటే తక్కువ పరిమాణంలో ఉండాలి.
|
||||
linkExpiredAlt = లంకె గడువు ముగిసింది
|
||||
expiredPageHeader = ఈ లంకె గడువు ముగిసింది లేదా ముందు ఎప్పుడూ ఉనికిలో లేదు!
|
||||
notSupportedHeader = మీ విహారిణికి మద్దతు లేదు.
|
||||
notSupportedLink = నా విహారిణికి ఎందుకు మద్దతు లేదు?
|
||||
notSupportedOutdatedDetail = దురదృష్టవశాత్తు Firefox యొక్క ఈ వెర్షన్ Firefox సాంకేతికతను పంపే వెబ్ సాంకేతికతకు మద్దతు ఇవ్వదు. మీరు మీ బ్రౌజర్ని నవీకరించాలి.
|
||||
updateFirefox = Firefoxను నవీకరించు
|
||||
downloadFirefoxButtonSub = ఉచిత దిగుమతులు
|
||||
uploadedFile = దస్త్రం
|
||||
copyFileList = URL నకలుతీయి
|
||||
# expiryFileList is used as a column header
|
||||
expiryFileList = ఇంతలో గడువుతీరును
|
||||
deleteFileList = తొలగించు
|
||||
nevermindButton = పర్వాలేదు
|
||||
legalHeader = నిబంధనలు మరియు గోప్యత
|
||||
deletePopupText = ఈ ఫైలును తొలగించాలా?
|
||||
deletePopupYes = అవును
|
||||
deletePopupCancel = రద్దుచేయి
|
||||
deleteButtonHover = తొలగించు
|
||||
copyUrlHover = URLను నకలు చేయండి
|
||||
footerLinkLegal = చట్టపరమైన
|
||||
# Test Pilot is a proper name and should not be localized.
|
||||
footerLinkAbout = టెస్ట్ పైలట్ గురించి
|
||||
footerLinkPrivacy = గోప్యత
|
||||
footerLinkTerms = నియమాలు
|
||||
footerLinkCookies = కుకీలు
|
||||
requirePasswordCheckbox = ఈ ఫైల్ను దింపుకోటానికి సంకేతపదం అవసరం
|
||||
addPasswordButton = సంకేతపదం జోడించండి
|
||||
changePasswordButton = మార్చు
|
||||
passwordTryAgain = సరికాని సంకేతపదం. మళ్ళీ ప్రయత్నించండి.
|
||||
reportIPInfringement = మేధో సంపత్తి హక్కుల ఉల్లంఘనను నివేదించండి
|
||||
javascriptRequired = Firefox Sendకి జావాస్క్రిప్టు కావాలి
|
||||
whyJavascript = Firefox Sendకి జావాస్క్రిప్టు ఎందుకు కావాలి?
|
||||
enableJavascript = జావాస్క్రిప్టు చేతనంచేసి మళ్ళీ ప్రయత్నించండి.
|
||||
@@ -103,9 +41,86 @@ enableJavascript = జావాస్క్రిప్టు చేతనంచ
|
||||
expiresHoursMinutes = { $hours }గం { $minutes }ని
|
||||
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
|
||||
expiresMinutes = { $minutes }ని
|
||||
# A short status message shown when a password is successfully set
|
||||
passwordIsSet = సంకేతపదం అమరింది
|
||||
# A short status message shown when the user enters a long password
|
||||
maxPasswordLength = సంకేతపదం గరిష్ఠ పొడవు: { $length }
|
||||
# A short status message shown when there was an error setting the password
|
||||
passwordSetError = ఈ సంకేతపదం పెట్టలేకపోయాం
|
||||
|
||||
## Send version 2 strings
|
||||
|
||||
# Firefox Send, Send, Firefox, Mozilla are proper names and should not be localized
|
||||
-send-brand = Firefox Send
|
||||
-send-short-brand = పంపించు
|
||||
-firefox = Firefox
|
||||
-mozilla = Mozilla
|
||||
timespanMinutes =
|
||||
{ $num ->
|
||||
[one] 1 నిమిషం
|
||||
*[other] { $num } నిమిషాలు
|
||||
}
|
||||
timespanDays =
|
||||
{ $num ->
|
||||
[one] 1 రోజు
|
||||
*[other] { $num } రోజులు
|
||||
}
|
||||
timespanWeeks =
|
||||
{ $num ->
|
||||
[one] 1 వారం
|
||||
*[other] { $num } వారాలు
|
||||
}
|
||||
fileCount =
|
||||
{ $num ->
|
||||
[one] 1 ఫైలు
|
||||
*[other] { $num } ఫైళ్లు
|
||||
}
|
||||
# byte abbreviation
|
||||
bytes = B
|
||||
# kibibyte abbreviation
|
||||
kb = KB
|
||||
# mebibyte abbreviation
|
||||
mb = MB
|
||||
# gibibyte abbreviation
|
||||
gb = GB
|
||||
# localized number and byte abbreviation. example "2.5MB"
|
||||
fileSize = { $num }{ $units }
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
totalSize = మొత్తం పరిమాణం: { $size }
|
||||
# the next line after the colon contains a file name
|
||||
copyLinkDescription = మీ ఫైలును భాగస్వామ్యం చేయడానికి ఈ లంకెను నకలు చేయండి:
|
||||
copyLinkButton = లంకెను నకలుతీయి
|
||||
downloadTitle = ఫైళ్లను దింపుకోండి
|
||||
expiredTitle = ఈ లంకె గడువు ముగిసింది.
|
||||
downloadFirefox = { -firefox } ను దింపుకోండి
|
||||
legalTitle = { -send-short-brand } గోప్యతా నోటీసు
|
||||
legalDateStamp = వెర్షన్ 1.0, మార్చి 12, 2019 నాటిది
|
||||
# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example "2d 11h 56m"
|
||||
expiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m
|
||||
addFilesButton = ఎక్కించడానికి ఫైళ్ళను ఎంచుకోండి
|
||||
uploadButton = ఎక్కించు
|
||||
# the first part of the string 'Drag and drop files or click to send up to 1GB'
|
||||
dragAndDropFiles = ఫైళ్ళను లాగండి మరియు వదలండి
|
||||
# the second part of the string 'Drag and drop files or click to send up to 1GB'
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
orClickWithSize = లేదా { $size } వరకు పంపడానికి నొక్కండి
|
||||
addPassword = సంకేతపదంతో రక్షించండి
|
||||
emailPlaceholder = ఈ ఈమెయిలును ఇవ్వండి
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
signInSizeBump = { $size } వరకు పంపడానికి ప్రవేశించండి
|
||||
signInOnlyButton = ప్రవేశించండి
|
||||
accountBenefitTitle = ఒక { -firefox } ఖాతాని సృష్టించండి లేదా ప్రవేశించండి
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
accountBenefitLargeFiles = { $size } పరిమాణం ఫైళ్ళ వరకు పంచుకోండి
|
||||
accountBenefitDownloadCount = ఫైళ్లను ఎక్కువ మందితో పంచుకోండి
|
||||
accountBenefitSync = ఏదైనా పరికరం నుండి పంచుకున్న ఫైళ్ళను నిర్వహించండి
|
||||
signOut = నిష్క్రమించు
|
||||
okButton = సరే
|
||||
downloadingTitle = దింపుకుంటోంది
|
||||
noStreamsWarning = ఈ బ్రౌజర్ ఈ ఫైలును పెద్దగా డీక్రిప్ట్ చేయలేకపోవచ్చు.
|
||||
noStreamsOptionCopy = మరొక బ్రౌజర్లో తెరవడానికి లంకెను నకలు చేయండి
|
||||
noStreamsOptionFirefox = మా అభిమాన బ్రౌజర్ను ప్రయత్నించండి
|
||||
noStreamsOptionDownload = ఈ బ్రౌజర్తో కొనసాగించండి
|
||||
downloadFirefoxPromo = { -send-short-brand } క్రొత్త { -firefox } ద్వారా మీ ముందుకు తీసుకురాబడుతుంది.
|
||||
# the next line after the colon contains a file name
|
||||
shareLinkDescription = మీ ఫైలుకు లంకెను పంచుకోండి:
|
||||
shareLinkButton = లంకెను పంచుకోండి
|
||||
learnMore = ఇంకా తెలుసుకోండి.
|
||||
|
||||
146
public/locales/th/send.ftl
Normal file
146
public/locales/th/send.ftl
Normal file
@@ -0,0 +1,146 @@
|
||||
# Firefox Send is a brand name and should not be localized.
|
||||
title = Firefox Send
|
||||
siteFeedback = ข้อคิดเห็น
|
||||
importingFile = กำลังนำเข้า…
|
||||
encryptingFile = กำลังเข้ารหัส…
|
||||
decryptingFile = กำลังถอดรหัส…
|
||||
downloadCount =
|
||||
{ $num ->
|
||||
*[other] { $num } การดาวน์โหลด
|
||||
}
|
||||
timespanHours =
|
||||
{ $num ->
|
||||
*[other] { $num } ชั่วโมง
|
||||
}
|
||||
copiedUrl = คัดลอกแล้ว!
|
||||
unlockInputPlaceholder = รหัสผ่าน
|
||||
unlockButtonLabel = ปลดล็อก
|
||||
downloadButtonLabel = ดาวน์โหลด
|
||||
downloadFinish = การดาวน์โหลดเสร็จสมบูรณ์
|
||||
fileSizeProgress = ({ $partialSize } จาก { $totalSize })
|
||||
sendYourFilesLink = ลองใช้ Firefox Send
|
||||
errorPageHeader = มีบางอย่างผิดพลาด!
|
||||
fileTooBig = ไฟล์นั้นใหญ่เกินกว่าจะอัปโหลดได้ ไฟล์ที่จะอัปโหลดควรมีขนาดน้อยกว่า { $size }
|
||||
linkExpiredAlt = ลิงก์หมดอายุแล้ว
|
||||
notSupportedHeader = ไม่รองรับเบราว์เซอร์ของคุณ
|
||||
notSupportedLink = ทำไมจึงไม่รองรับเบราว์เซอร์ของฉัน?
|
||||
notSupportedOutdatedDetail = น่าเสียดายที่ Firefox รุ่นนี้ไม่สนับสนุนเทคโนโลยีเว็บที่ขับเคลื่อน Firefox Send คุณจะต้องอัปเดตเบราว์เซอร์ของคุณ
|
||||
updateFirefox = อัปเดต Firefox
|
||||
deletePopupCancel = ยกเลิก
|
||||
deleteButtonHover = ลบ
|
||||
footerLinkLegal = ข้อกฎหมาย
|
||||
footerLinkPrivacy = ความเป็นส่วนตัว
|
||||
footerLinkCookies = คุกกี้
|
||||
passwordTryAgain = รหัสผ่านไม่ถูกต้อง ลองอีกครั้ง
|
||||
javascriptRequired = Firefox Send จำเป็นต้องใช้ JavaScript
|
||||
whyJavascript = ทำไม Firefox Send จึงจำเป็นต้องใช้ JavaScript?
|
||||
enableJavascript = โปรดเปิดใช้งาน JavaScript แล้วลองอีกครั้ง
|
||||
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
|
||||
expiresHoursMinutes = { $hours } ชม. { $minutes } นาที
|
||||
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
|
||||
expiresMinutes = { $minutes } นาที
|
||||
# A short status message shown when the user enters a long password
|
||||
maxPasswordLength = ความยาวรหัสผ่านสูงสุด: { $length }
|
||||
# A short status message shown when there was an error setting the password
|
||||
passwordSetError = ไม่สามารถตั้งรหัสผ่านนี้ได้
|
||||
|
||||
## Send version 2 strings
|
||||
|
||||
# Firefox Send, Send, Firefox, Mozilla are proper names and should not be localized
|
||||
-send-brand = Firefox Send
|
||||
-send-short-brand = Send
|
||||
-firefox = Firefox
|
||||
-mozilla = Mozilla
|
||||
introTitle = การแบ่งปันไฟล์ที่ง่ายและเป็นส่วนตัว
|
||||
introDescription = { -send-brand } ให้คุณแบ่งปันไฟล์ด้วยการเข้ารหัสจากต้นทางถึงปลายทางและลิงก์ที่หมดอายุโดยอัตโนมัติ คุณจึงสามารถเก็บสิ่งที่คุณแบ่งปันไว้เป็นส่วนตัวและตรวจสอบให้แน่ใจว่าข้อมูลของคุณจะไม่ออนไลน์ตลอดไป
|
||||
notifyUploadEncryptDone = ไฟล์ของคุณได้รับการเข้ารหัสและพร้อมส่ง
|
||||
# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'
|
||||
archiveExpiryInfo = หมดอายุหลังจาก { $downloadCount } หรือ { $timespan }
|
||||
timespanMinutes =
|
||||
{ $num ->
|
||||
*[other] { $num } นาที
|
||||
}
|
||||
timespanDays =
|
||||
{ $num ->
|
||||
*[other] { $num } วัน
|
||||
}
|
||||
timespanWeeks =
|
||||
{ $num ->
|
||||
*[other] { $num } สัปดาห์
|
||||
}
|
||||
fileCount =
|
||||
{ $num ->
|
||||
*[other] { $num } ไฟล์
|
||||
}
|
||||
# byte abbreviation
|
||||
bytes = B
|
||||
# kibibyte abbreviation
|
||||
kb = KB
|
||||
# mebibyte abbreviation
|
||||
mb = MB
|
||||
# gibibyte abbreviation
|
||||
gb = GB
|
||||
# localized number and byte abbreviation. example "2.5MB"
|
||||
fileSize = { $num }{ $units }
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
totalSize = ขนาดรวม: { $size }
|
||||
# the next line after the colon contains a file name
|
||||
copyLinkDescription = คัดลอกลิงก์เพื่อแบ่งปันไฟล์ของคุณ:
|
||||
copyLinkButton = คัดลอกลิงก์
|
||||
downloadTitle = ดาวน์โหลดไฟล์
|
||||
downloadDescription = ไฟล์นี้ถูกแบ่งปันผ่าน { -send-brand } พร้อมการเข้ารหัสจากต้นทางถึงปลายทางและลิงก์ที่หมดอายุโดยอัตโนมัติ
|
||||
trySendDescription = ลองใช้ { -send-brand } สำหรับการแบ่งปันไฟล์ที่ง่ายและปลอดภัย
|
||||
# count will always be > 10
|
||||
tooManyFiles =
|
||||
{ $count ->
|
||||
*[other] สามารถอัปโหลดได้ครั้งละ { $count } ไฟล์เท่านั้น
|
||||
}
|
||||
# count will always be > 10
|
||||
tooManyArchives =
|
||||
{ $count ->
|
||||
*[other] สามารถอัปโหลดไฟล์เก็บถาวรได้เพียง { $count } ไฟล์เท่านั้น
|
||||
}
|
||||
expiredTitle = ลิงก์นี้หมดอายุแล้ว
|
||||
notSupportedDescription = { -send-brand } จะไม่ทำงานกับเบราว์เซอร์นี้ { -send-short-brand } จะทำงานได้ดีที่สุดกับ { -firefox } รุ่นล่าสุด และจะทำงานกับเบราว์เซอร์ส่วนใหญ่ที่เป็นรุ่นปัจจุบัน
|
||||
downloadFirefox = ดาวน์โหลด { -firefox }
|
||||
legalTitle = ประกาศความเป็นส่วนตัวของ { -send-short-brand }
|
||||
legalDateStamp = รุ่น 1.0 วันที่ 12 มีนาคม 2019
|
||||
# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example "2d 11h 56m"
|
||||
expiresDaysHoursMinutes = { $days } วัน { $hours } ชม. { $minutes } นาที
|
||||
addFilesButton = เลือกไฟล์ที่จะอัปโหลด
|
||||
uploadButton = อัปโหลด
|
||||
# the first part of the string 'Drag and drop files or click to send up to 1GB'
|
||||
dragAndDropFiles = ลากแล้วปล่อยไฟล์
|
||||
# the second part of the string 'Drag and drop files or click to send up to 1GB'
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
orClickWithSize = หรือคลิกเพื่อส่งได้ถึง { $size }
|
||||
addPassword = ปกป้องด้วยรหัสผ่าน
|
||||
emailPlaceholder = ป้อนอีเมลของคุณ
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
signInSizeBump = ลงชื่อเข้าเพื่อส่งได้ถึง { $size }
|
||||
signInOnlyButton = ลงชื่อเข้า
|
||||
accountBenefitTitle = สร้างบัญชี { -firefox } หรือลงชื่อเข้า
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
accountBenefitLargeFiles = แบ่งปันไฟล์สูงสุดถึง { $size }
|
||||
accountBenefitDownloadCount = แบ่งปันไฟล์กับผู้คนมากขึ้น
|
||||
accountBenefitTimeLimit =
|
||||
{ $count ->
|
||||
*[other] ให้ลิงก์ใช้งานได้นานถึง { $count } วัน
|
||||
}
|
||||
accountBenefitSync = จัดการไฟล์ที่แบ่งปันจากอุปกรณ์ใด ๆ
|
||||
accountBenefitMoz = เรียนรู้เกี่ยวกับบริการ { -mozilla } อื่น ๆ
|
||||
signOut = ลงชื่อออก
|
||||
okButton = ตกลง
|
||||
downloadingTitle = กำลังดาวน์โหลด
|
||||
noStreamsWarning = เบราว์เซอร์นี้อาจไม่สามารถถอดรหัสไฟล์ขนาดใหญ่เท่านี้ได้
|
||||
noStreamsOptionCopy = คัดลอกลิงก์เพื่อเปิดในเบราว์เซอร์อื่น
|
||||
noStreamsOptionFirefox = ลองเบราว์เซอร์โปรดของเรา
|
||||
noStreamsOptionDownload = ดำเนินการต่อด้วยเบราว์เซอร์นี้
|
||||
downloadFirefoxPromo = { -send-short-brand } สนับสนุนโดย { -firefox } โฉมใหม่
|
||||
# the next line after the colon contains a file name
|
||||
shareLinkDescription = แบ่งปันลิงก์ไปยังไฟล์ของคุณ:
|
||||
shareLinkButton = แบ่งปันลิงก์
|
||||
# $name is the name of the file
|
||||
shareMessage = ดาวน์โหลด “{ $name }” ด้วย { -send-brand }: การแบ่งปันไฟล์ที่ง่ายและเป็นส่วนตัว
|
||||
trailheadPromo = มีวิธีปกป้องความเป็นส่วนตัวของคุณ เข้าร่วม Firefox
|
||||
learnMore = เรียนรู้เพิ่มเติม
|
||||
@@ -160,3 +160,5 @@ shareLinkDescription = Надішліть посилання на свій фа
|
||||
shareLinkButton = Поділитись посиланням
|
||||
# $name is the name of the file
|
||||
shareMessage = Завантажте “{ $name }” з { -send-brand }: простий та безпечний обмін файлами
|
||||
trailheadPromo = Існує спосіб захистити вашу приватність. Приєднуйтесь до Firefox.
|
||||
learnMore = Докладніше.
|
||||
|
||||
@@ -87,7 +87,7 @@ totalSize = Tổng kích thước: { $size }
|
||||
# the next line after the colon contains a file name
|
||||
copyLinkDescription = Sao chép liên kết để chia sẻ tập tin của bạn:
|
||||
copyLinkButton = Sao chép liên kết
|
||||
downloadTitle = Tải tập tin
|
||||
downloadTitle = Tải xuống tập tin
|
||||
downloadDescription = Tập tin này đã được chia sẻ qua { -send-brand } với mã hóa đầu cuối và liên kết tự động hết hạn.
|
||||
trySendDescription = Hãy thử { -send-brand } để chia sẻ tập tin đơn giản, an toàn.
|
||||
# count will always be > 10
|
||||
|
||||
@@ -33,7 +33,7 @@ deleteButtonHover = ⴽⴽⵙ
|
||||
footerLinkLegal = ⵓⵙⴹⵉⴼ
|
||||
footerLinkPrivacy = ⵜⵉⵏⵏⵓⵜⵍⴰ
|
||||
footerLinkCookies = ⵉⴽⵓⴽⵉⵜⵏ
|
||||
passwordTryAgain = ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ ⵓⵔ ⵢⵓⵖⴷⵏ. ⴰⵔⵎ ⴷⴰⵖ.
|
||||
passwordTryAgain = ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ ⵓⵔ ⵢⵓⵖⵉⴷⵏ. ⴰⵔⵎ ⴷⴰⵖ.
|
||||
javascriptRequired = ⴷⴰ ⵉⵜⵜⴰⵙⵔ ⴼⴰⵢⵔⴼⵓⴽⵙ ⵙⵉⵏⴷ ⵊⴰⴼⴰⵙⴽⵔⵉⴱⵜ
|
||||
whyJavascript = ⵎⴰⵖⴼ ⴷⴰ ⵉⵜⵜⴰⵙⵔ ⴼⴰⵢⵔⴼⵓⴽⵙ ⵙⵉⵏⴷ ⵊⴰⴼⴰⵙⴽⵔⵉⴱⵜ?
|
||||
enableJavascript = ⵎⴽ ⵜⵓⴼⴰⵎ, ⵙⵏⵓⵛⵛⴳⴰⵜ ⵊⴰⴼⴰⵙⴽⵔⵉⴱⵜ, ⵜⴰⵔⵎⵎ ⴷⴰⵖ.
|
||||
@@ -95,7 +95,7 @@ copyLinkDescription = ⵙⵙⵏⵖⵍⴰⵜ ⴰⵙⵖⵏ ⴰⴼⴰⴷ ⴰⴷ ⵜ
|
||||
copyLinkButton = ⵙⵙⵏⵖⵍ ⴰⵙⵖⵏ
|
||||
downloadTitle = ⴰⴳⵎ ⵉⴼⵓⵢⵍⴰ
|
||||
downloadDescription = ⵉⵜⵜⵓⴱⴹⴰ ⵓⴼⴰⵢⵍⵓ ⴰ ⵙⴳ { -send-brand } ⵙ ⵓⵙⵙⵏⵜⵍ ⵙⴳ ⵜⴰⵎⴰ ⴰⵔ ⵜⴰⵎⴰ ⴷ ⵢⴰⵏ ⵓⵙⵖⵏ ⵏⵏⴰ ⵉⵜⵜⵎⵎⵜⴰⵜⵏ ⵙ ⵓⵡⵔⵎⴰⵏ.
|
||||
trySendDescription = ⴰⵔⵎ { -send-brand } ⵉ ⵓⴱⵟⵟⵓ ⴰⴼⵔⴰⵔ ⴷ ⵡⵓⴼⵔⵉⴳ.
|
||||
trySendDescription = ⴰⵔⵎⴰⵜ { -send-brand } ⵉ ⵓⴱⵟⵟⵓ ⴰⴼⵔⴰⵔ ⴷ ⵡⵓⴼⵔⵉⴳ ⵏ ⵉⴼⵓⵢⵍⴰ.
|
||||
# count will always be > 10
|
||||
tooManyFiles =
|
||||
{ $count ->
|
||||
@@ -126,7 +126,7 @@ addPassword = ⴰⵔⵢ ⵙ ⵜⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ
|
||||
emailPlaceholder = ⵙⵙⴽⵛⵎⴰⵜ ⵉⵎⴰⵢⵍ ⵏⵏⵓⵏ
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
signInSizeBump = ⴽⵛⵎ ⴰⴼⴰⴷ ⴰⴷ ⵜⴰⵣⵏⴷ ⴰⵔ { $size }
|
||||
signInButton = ⴽⵛⵎ/ⵣⵎⵎⴻⵎ
|
||||
signInOnlyButton = ⴽⵛⵎ
|
||||
accountBenefitTitle = ⵙⵏⴼⵍⵓⵍ ⴰⵎⵉⴹⴰⵏ ⵏ { -firefox } ⵏⵉⵖ ⵜⵣⵎⵎⴻⵎⴷ
|
||||
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
|
||||
accountBenefitLargeFiles = ⴱⴹⵓ ⵉⴼⵓⵢⵍⴰ ⴰⵔ { $size }
|
||||
@@ -145,3 +145,11 @@ noStreamsWarning = ⵉⵣⵎⵔ ⵓⵎⵙⵙⴰⵔⴰ ⴰ ⴰⴷ ⵓⵔ ⵉⵖ
|
||||
noStreamsOptionCopy = ⵙⵙⵏⵖⵍⴰⵜ ⴰⵙⵖⵏ ⴰⴼⴰⴷ ⴰⴷ ⵜ ⵜⵕⵥⵎⵎ ⴳ ⴽⵔⴰ ⵏ ⵓⵎⵙⵙⴰⵔⴰ ⵢⴰⴹⵏ
|
||||
noStreamsOptionFirefox = ⴰⵔⵎⴰⵜ ⴰⵎⵙⵙⴰⵔⴰ ⵏⵏⵖ ⴰⵎⵓⴼⴰⵢ
|
||||
noStreamsOptionDownload = ⵙⵎⴷ ⵙ ⵓⵎⵙⵙⴰⵔⴰ ⴰ
|
||||
downloadFirefoxPromo = ⵉⵜⵜⵓⵙⵓⵎⵔ ⴰⵡⵏ { -send-short-brand } ⵙⴳ ⵖⵓⵔ { -firefox } ⴰⵎⴰⵢⵏⵓ ⴰⴽⴽⵯ.
|
||||
# the next line after the colon contains a file name
|
||||
shareLinkDescription = ⴱⴹⵓⵢⴰⵜ ⴰⵙⵖⵏ ⵖⵔ ⵓⴼⴰⵢⵍⵓ ⵏⵏⵓⵏ:
|
||||
shareLinkButton = ⴱⴹⵓ ⴰⵙⵖⵏ
|
||||
# $name is the name of the file
|
||||
shareMessage = ⴰⴳⵎⴰⵜ "{ $name }" ⵙ { -send-brand }: ⴰⴱⵟⵟⵓ ⴰⴼⵔⴰⵔ ⴷ ⵡⵓⵙⵍⵉⴳ ⵏ ⵉⴼⵓⵢⵍⴰ
|
||||
trailheadPromo = ⵜⵍⵍⴰ ⵢⴰⵜ ⵜⵖⴰⵔⴰⵙⵜ ⴰⴼⴰⴷ ⴰⴷ ⵜⴼⵔⴳⵎ ⵜⵉⵏⵏⵓⵜⵍⴰ ⵏⵏⵓⵏ. ⵍⴽⵎⴰⵜ ⴼⴰⵢⵔⴼⵓⴽⵙ.
|
||||
learnMore = ⵙⵙⵏ ⵓⴳⴳⴰⵔ.
|
||||
|
||||
@@ -55,7 +55,7 @@ introTitle = 簡單而私密的檔案共享服務
|
||||
introDescription = { -send-brand } 讓您可透過點對點加密的方式來分享檔案,並提供會自動失效的鏈結。這樣一來就可以保留分享時的隱私,也確保檔案不會永久保存於網路上。
|
||||
notifyUploadEncryptDone = 已加密您的檔案,可以傳送
|
||||
# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'
|
||||
archiveExpiryInfo = { $downloadCount } 次下載或 { $timespan } 後失效
|
||||
archiveExpiryInfo = { $downloadCount } 或 { $timespan } 後失效
|
||||
timespanMinutes =
|
||||
{ $num ->
|
||||
*[other] { $num } 分鐘
|
||||
|
||||
@@ -19,8 +19,8 @@ exec(cmd)
|
||||
const locales = Object.keys(summary)
|
||||
.filter(locale => {
|
||||
const loc = summary[locale];
|
||||
const hasMissing = loc.hasOwnProperty('missing');
|
||||
const hasErrors = loc.hasOwnProperty('errors');
|
||||
const hasMissing = Object.prototype.hasOwnProperty.call(loc, 'missing');
|
||||
const hasErrors = Object.prototype.hasOwnProperty.call(loc, 'errors');
|
||||
return !hasMissing && !hasErrors;
|
||||
})
|
||||
.sort();
|
||||
|
||||
@@ -33,7 +33,7 @@ function filterErrors(details) {
|
||||
.sort()
|
||||
.map(locale => {
|
||||
const data = details[locale]
|
||||
.filter(item => item.hasOwnProperty('error'))
|
||||
.filter(item => Object.prototype.hasOwnProperty.call(item, 'error'))
|
||||
.map(({ error }) => error);
|
||||
return { locale, data };
|
||||
})
|
||||
|
||||
13
scripts/sync-npm-dependencies.sh
Executable file
13
scripts/sync-npm-dependencies.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "checking package-lock.json for changes"
|
||||
IFS=' '
|
||||
read -ra G_PARAMS <<< "$HUSKY_GIT_PARAMS"
|
||||
PREV=${G_PARAMS[0]}
|
||||
NEXT=${G_PARAMS[1]}
|
||||
if [ "$PREV" != "$NEXT" ]; then
|
||||
DIFF=$(git diff $PREV $NEXT package-lock.json)
|
||||
if [ "$DIFF" != "" ]; then
|
||||
npm install
|
||||
fi
|
||||
fi
|
||||
@@ -3,7 +3,7 @@ const routes = require('../routes');
|
||||
const pages = require('../routes/pages');
|
||||
const tests = require('../../test/frontend/routes');
|
||||
const express = require('express');
|
||||
const expressWs = require('express-ws');
|
||||
const expressWs = require('@dannycoates/express-ws');
|
||||
const morgan = require('morgan');
|
||||
const config = require('../config');
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
const express = require('express');
|
||||
const path = require('path');
|
||||
const Raven = require('raven');
|
||||
const Sentry = require('@sentry/node');
|
||||
const config = require('../config');
|
||||
const routes = require('../routes');
|
||||
const pages = require('../routes/pages');
|
||||
const expressWs = require('express-ws');
|
||||
const expressWs = require('@dannycoates/express-ws');
|
||||
|
||||
if (config.sentry_dsn) {
|
||||
Raven.config(config.sentry_dsn).install();
|
||||
Sentry.init({ dsn: config.sentry_dsn });
|
||||
}
|
||||
|
||||
const app = express();
|
||||
|
||||
@@ -2,7 +2,7 @@ const assets = require('../../common/assets');
|
||||
const routes = require('../routes');
|
||||
const pages = require('../routes/pages');
|
||||
const tests = require('../../test/frontend/routes');
|
||||
const expressWs = require('express-ws');
|
||||
const expressWs = require('@dannycoates/express-ws');
|
||||
|
||||
module.exports = function(app, devServer) {
|
||||
assets.setMiddleware(devServer.middleware);
|
||||
|
||||
@@ -8,12 +8,10 @@ if (config.sentry_id) {
|
||||
//eslint-disable-next-line node/no-missing-require
|
||||
const version = require('../dist/version.json');
|
||||
sentry = `
|
||||
var RAVEN_CONFIG = {
|
||||
var SENTRY_CONFIG = {
|
||||
dsn: '${config.sentry_id}',
|
||||
release: '${version.version}',
|
||||
tags: {
|
||||
commit: '${version.commit}'
|
||||
},
|
||||
dataCallback: function (data) {
|
||||
beforeSend: function (data) {
|
||||
var hash = window.location.hash;
|
||||
if (hash) {
|
||||
return JSON.parse(JSON.stringify(data).replace(new RegExp(hash.slice(1), 'g'), ''));
|
||||
@@ -21,7 +19,6 @@ var RAVEN_CONFIG = {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
var SENTRY_ID = '${config.sentry_id}';
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { FluentBundle } = require('fluent');
|
||||
const { FluentBundle } = require('@fluent/bundle');
|
||||
const localesPath = path.resolve(__dirname, '../public/locales');
|
||||
const locales = fs.readdirSync(localesPath);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ const { availableLanguages } = require('../../package.json');
|
||||
const config = require('../config');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { negotiateLanguages } = require('fluent-langneg');
|
||||
const { negotiateLanguages } = require('@fluent/langneg');
|
||||
const langData = require('cldr-core/supplemental/likelySubtags.json');
|
||||
|
||||
// We return early in the middleware if the lang header is long.
|
||||
|
||||
@@ -67,7 +67,10 @@ module.exports = function(app) {
|
||||
}
|
||||
app.use(function(req, res, next) {
|
||||
res.set('Pragma', 'no-cache');
|
||||
res.set('Cache-Control', 'no-cache');
|
||||
res.set(
|
||||
'Cache-Control',
|
||||
'private, no-cache, no-store, must-revalidate, max-age=0'
|
||||
);
|
||||
next();
|
||||
});
|
||||
app.use(bodyParser.json());
|
||||
@@ -79,6 +82,7 @@ module.exports = function(app) {
|
||||
app.get('/error', language, pages.blank);
|
||||
app.get('/oauth', language, pages.blank);
|
||||
app.get('/legal', language, pages.legal);
|
||||
app.get('/login', language, pages.index);
|
||||
app.get('/app.webmanifest', language, require('./webmanifest'));
|
||||
app.get(`/download/:id${ID_REGEX}`, language, pages.download);
|
||||
app.get('/unsupported/:reason', language, pages.unsupported);
|
||||
@@ -104,6 +108,7 @@ module.exports = function(app) {
|
||||
app.post(`/api/info/:id${ID_REGEX}`, auth.owner, require('./info'));
|
||||
app.post('/api/metrics', require('./metrics'));
|
||||
app.get('/__version__', function(req, res) {
|
||||
// eslint-disable-next-line node/no-missing-require
|
||||
res.sendFile(require.resolve('../../dist/version.json'));
|
||||
});
|
||||
|
||||
|
||||
@@ -3,12 +3,11 @@ const storage = require('../storage');
|
||||
const config = require('../config');
|
||||
const mozlog = require('../log');
|
||||
const Limiter = require('../limiter');
|
||||
const wsStream = require('websocket-stream/stream');
|
||||
const fxa = require('../fxa');
|
||||
const { statUploadEvent } = require('../amplitude');
|
||||
const { encryptedSize } = require('../../app/utils');
|
||||
|
||||
const { Duplex } = require('stream');
|
||||
const { Transform } = require('stream');
|
||||
|
||||
const log = mozlog('send.upload');
|
||||
|
||||
@@ -76,25 +75,19 @@ module.exports = function(ws, req) {
|
||||
})
|
||||
);
|
||||
const limiter = new Limiter(encryptedSize(maxFileSize));
|
||||
const flowControl = new Duplex({
|
||||
read() {
|
||||
ws.resume();
|
||||
},
|
||||
write(chunk, encoding, callback) {
|
||||
const eof = new Transform({
|
||||
transform: function(chunk, encoding, callback) {
|
||||
if (chunk.length === 1 && chunk[0] === 0) {
|
||||
this.push(null);
|
||||
} else {
|
||||
if (!this.push(chunk)) {
|
||||
ws.pause();
|
||||
}
|
||||
this.push(chunk);
|
||||
}
|
||||
callback();
|
||||
}
|
||||
});
|
||||
const wsStream = ws.constructor.createWebSocketStream(ws);
|
||||
|
||||
fileStream = wsStream(ws, { binary: true })
|
||||
.pipe(flowControl)
|
||||
.pipe(limiter); // limiter needs to be the last in the chain
|
||||
fileStream = wsStream.pipe(eof).pipe(limiter); // limiter needs to be the last in the chain
|
||||
|
||||
await storage.set(newId, fileStream, meta, timeLimit);
|
||||
|
||||
@@ -126,8 +119,8 @@ module.exports = function(ws, req) {
|
||||
error: e === 'limit' ? 413 : 500
|
||||
})
|
||||
);
|
||||
ws.close();
|
||||
}
|
||||
}
|
||||
ws.close();
|
||||
});
|
||||
};
|
||||
|
||||
@@ -22,7 +22,7 @@ class GCSStorage {
|
||||
.pipe(
|
||||
this.bucket.file(id).createWriteStream({
|
||||
validation: false,
|
||||
resumable: false
|
||||
resumable: true
|
||||
})
|
||||
)
|
||||
.on('error', reject)
|
||||
|
||||
429
tailwind.config.js
Normal file
429
tailwind.config.js
Normal file
@@ -0,0 +1,429 @@
|
||||
const colors = {
|
||||
transparent: 'transparent',
|
||||
|
||||
black: '#22292f',
|
||||
'grey-darkest': '#4a4a4f',
|
||||
'grey-darker': '#606f7b',
|
||||
'grey-dark': '#8795a1',
|
||||
grey: '#B1B1B3',
|
||||
'grey-light': '#dae1e7',
|
||||
'grey-banner': '#f0f0f4',
|
||||
'grey-transparent': 'hsla(250, 13%, 9%, .2)',
|
||||
'grey-lighter': '#f1f5f8',
|
||||
'grey-lightest': '#F9F9FA',
|
||||
white: '#ffffff',
|
||||
|
||||
'red-darkest': '#3b0d0c',
|
||||
'red-darker': '#621b18',
|
||||
'red-dark': '#cc1f1a',
|
||||
red: '#e3342f',
|
||||
'red-light': '#ef5753',
|
||||
'red-lighter': '#f9acaa',
|
||||
'red-lightest': '#fcebea',
|
||||
|
||||
'orange-darkest': '#462a16',
|
||||
'orange-darker': '#613b1f',
|
||||
'orange-dark': '#de751f',
|
||||
orange: '#f6993f',
|
||||
'orange-light': '#faad63',
|
||||
'orange-lighter': '#fcd9b6',
|
||||
'orange-lightest': '#fff5eb',
|
||||
|
||||
'yellow-darkest': '#453411',
|
||||
'yellow-darker': '#684f1d',
|
||||
'yellow-dark': '#f2d024',
|
||||
yellow: '#ffed4a',
|
||||
'yellow-light': '#fff382',
|
||||
'yellow-lighter': '#fff9c2',
|
||||
'yellow-lightest': '#fcfbeb',
|
||||
|
||||
'green-darkest': '#003706',
|
||||
'green-darker': '#006504',
|
||||
'green-dark': '#058b00',
|
||||
green: '#12bc00',
|
||||
'green-light': '#51d88a',
|
||||
'green-lighter': '#a2f5bf',
|
||||
'green-lightest': '#e3fcec',
|
||||
|
||||
'teal-darkest': '#0d3331',
|
||||
'teal-darker': '#20504f',
|
||||
'teal-dark': '#38a89d',
|
||||
teal: '#4dc0b5',
|
||||
'teal-light': '#64d5ca',
|
||||
'teal-lighter': '#a0f0ed',
|
||||
'teal-lightest': '#e8fffe',
|
||||
|
||||
'blue-darkest': '#002275',
|
||||
'blue-darker': '#003eaa',
|
||||
'blue-dark': '#0060df',
|
||||
blue: '#0a84ff',
|
||||
'blue-light': '#6cb2eb',
|
||||
'blue-lighter': '#bcdefa',
|
||||
'blue-lightest': '#eff8ff',
|
||||
|
||||
'indigo-darkest': '#191e38',
|
||||
'indigo-darker': '#2f365f',
|
||||
'indigo-dark': '#5661b3',
|
||||
indigo: '#6574cd',
|
||||
'indigo-light': '#7886d7',
|
||||
'indigo-lighter': '#b2b7ff',
|
||||
'indigo-lightest': '#e6e8ff',
|
||||
|
||||
'purple-darkest': '#21183c',
|
||||
'purple-darker': '#382b5f',
|
||||
'purple-dark': '#794acf',
|
||||
purple: '#9561e2',
|
||||
'purple-light': '#a779e9',
|
||||
'purple-lighter': '#d6bbfc',
|
||||
'purple-lightest': '#f3ebff',
|
||||
|
||||
'pink-darkest': '#451225',
|
||||
'pink-darker': '#6f213f',
|
||||
'pink-dark': '#eb5286',
|
||||
pink: '#f66d9b',
|
||||
'pink-light': '#fa7ea8',
|
||||
'pink-lighter': '#ffbbca',
|
||||
'pink-lightest': '#ffebef',
|
||||
cloud: 'rgba(255, 255, 255, 0.8)',
|
||||
violet: 'hsl(258, 57%, 35%)'
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
theme: {
|
||||
colors: colors,
|
||||
screens: {
|
||||
sm: '576px',
|
||||
md: '768px',
|
||||
lg: '992px',
|
||||
xl: '1200px'
|
||||
},
|
||||
fontFamily: {
|
||||
sans: [
|
||||
'Inter',
|
||||
'system-ui',
|
||||
'BlinkMacSystemFont',
|
||||
'-apple-system',
|
||||
'Segoe UI',
|
||||
'Roboto',
|
||||
'Oxygen',
|
||||
'Ubuntu',
|
||||
'Cantarell',
|
||||
'Fira Sans',
|
||||
'Droid Sans',
|
||||
'Helvetica Neue',
|
||||
'sans-serif'
|
||||
],
|
||||
serif: [
|
||||
'Constantia',
|
||||
'Lucida Bright',
|
||||
'Lucidabright',
|
||||
'Lucida Serif',
|
||||
'Lucida',
|
||||
'DejaVu Serif',
|
||||
'Bitstream Vera Serif',
|
||||
'Liberation Serif',
|
||||
'Georgia',
|
||||
'serif'
|
||||
],
|
||||
mono: [
|
||||
'Menlo',
|
||||
'Monaco',
|
||||
'Consolas',
|
||||
'Liberation Mono',
|
||||
'Courier New',
|
||||
'monospace'
|
||||
]
|
||||
},
|
||||
fontSize: {
|
||||
xs: '.75rem', // 12px
|
||||
sm: '.875rem', // 14px
|
||||
base: '1rem', // 16px
|
||||
lg: '1.125rem', // 18px
|
||||
xl: '1.25rem', // 20px
|
||||
'2xl': '1.5rem', // 24px
|
||||
'3xl': '2rem', // 32px
|
||||
'4xl': '2.25rem', // 36px
|
||||
'5xl': '3rem' // 48px
|
||||
},
|
||||
fontWeight: {
|
||||
hairline: 100,
|
||||
thin: 200,
|
||||
light: 300,
|
||||
normal: 400,
|
||||
medium: 500,
|
||||
semibold: 600,
|
||||
bold: 700,
|
||||
extrabold: 800,
|
||||
black: 900
|
||||
},
|
||||
lineHeight: {
|
||||
none: 1,
|
||||
tight: 1.25,
|
||||
normal: 1.5,
|
||||
loose: 1.75
|
||||
},
|
||||
letterSpacing: {
|
||||
tight: '-0.05em',
|
||||
normal: '0',
|
||||
wide: '0.05em'
|
||||
},
|
||||
textColor: colors,
|
||||
backgroundColor: colors,
|
||||
backgroundSize: {
|
||||
auto: 'auto',
|
||||
cover: 'cover',
|
||||
contain: 'contain'
|
||||
},
|
||||
borderWidth: {
|
||||
default: '1px',
|
||||
'0': '0',
|
||||
'2': '2px',
|
||||
'4': '4px',
|
||||
'8': '8px'
|
||||
},
|
||||
borderColor: global.Object.assign(
|
||||
{ default: colors['grey-light'] },
|
||||
colors
|
||||
),
|
||||
borderRadius: {
|
||||
none: '0',
|
||||
sm: '.125rem',
|
||||
default: '.25rem',
|
||||
lg: '.5rem',
|
||||
xl: '1rem',
|
||||
full: '9999px'
|
||||
},
|
||||
width: {
|
||||
auto: 'auto',
|
||||
px: '1px',
|
||||
'0': '0',
|
||||
'1': '0.25rem',
|
||||
'2': '0.5rem',
|
||||
'3': '0.75rem',
|
||||
'4': '1rem',
|
||||
'5': '1.25rem',
|
||||
'6': '1.5rem',
|
||||
'8': '2rem',
|
||||
'10': '2.5rem',
|
||||
'12': '3rem',
|
||||
'16': '4rem',
|
||||
'24': '6rem',
|
||||
'32': '8rem',
|
||||
'48': '12rem',
|
||||
'64': '16rem',
|
||||
'128': '32rem',
|
||||
'1/2': '50%',
|
||||
'1/3': '33.33333%',
|
||||
'2/3': '66.66667%',
|
||||
'1/4': '25%',
|
||||
'3/4': '75%',
|
||||
'1/5': '20%',
|
||||
'2/5': '40%',
|
||||
'3/5': '60%',
|
||||
'4/5': '80%',
|
||||
'1/6': '16.66667%',
|
||||
'5/6': '83.33333%',
|
||||
full: '100%',
|
||||
screen: '100vw'
|
||||
},
|
||||
height: {
|
||||
auto: 'auto',
|
||||
px: '1px',
|
||||
'0': '0',
|
||||
'1': '0.25rem',
|
||||
'2': '0.5rem',
|
||||
'3': '0.75rem',
|
||||
'4': '1rem',
|
||||
'5': '1.25rem',
|
||||
'6': '1.5rem',
|
||||
'8': '2rem',
|
||||
'10': '2.5rem',
|
||||
'12': '3rem',
|
||||
'16': '4rem',
|
||||
'24': '6rem',
|
||||
'32': '8rem',
|
||||
'48': '12rem',
|
||||
'64': '16rem',
|
||||
full: '100%',
|
||||
screen: '100vh'
|
||||
},
|
||||
minWidth: {
|
||||
'0': '0',
|
||||
full: '100%'
|
||||
},
|
||||
minHeight: {
|
||||
'0': '0',
|
||||
full: '100%',
|
||||
screen: '100vh'
|
||||
},
|
||||
maxWidth: {
|
||||
xs: '20rem',
|
||||
sm: '30rem',
|
||||
md: '40rem',
|
||||
lg: '50rem',
|
||||
xl: '60rem',
|
||||
'2xl': '70rem',
|
||||
'3xl': '80rem',
|
||||
'4xl': '90rem',
|
||||
'5xl': '100rem',
|
||||
full: '100%'
|
||||
},
|
||||
maxHeight: {
|
||||
full: '100%',
|
||||
'half-screen': '50vh',
|
||||
screen: '100vh'
|
||||
},
|
||||
padding: {
|
||||
px: '1px',
|
||||
'0': '0',
|
||||
'1': '0.25rem',
|
||||
'2': '0.5rem',
|
||||
'3': '0.75rem',
|
||||
'4': '1rem',
|
||||
'5': '1.25rem',
|
||||
'6': '1.5rem',
|
||||
'8': '2rem',
|
||||
'10': '2.5rem',
|
||||
'12': '3rem',
|
||||
'16': '4rem',
|
||||
'20': '5rem',
|
||||
'24': '6rem',
|
||||
'32': '8rem'
|
||||
},
|
||||
margin: {
|
||||
auto: 'auto',
|
||||
px: '1px',
|
||||
'0': '0',
|
||||
'1': '0.25rem',
|
||||
'2': '0.5rem',
|
||||
'3': '0.75rem',
|
||||
'4': '1rem',
|
||||
'5': '1.25rem',
|
||||
'6': '1.5rem',
|
||||
'8': '2rem',
|
||||
'10': '2.5rem',
|
||||
'12': '3rem',
|
||||
'16': '4rem',
|
||||
'20': '5rem',
|
||||
'24': '6rem',
|
||||
'32': '8rem',
|
||||
'-px': '-1px',
|
||||
'-1': '-0.25rem',
|
||||
'-2': '-0.5rem',
|
||||
'-3': '-0.75rem',
|
||||
'-4': '-1rem',
|
||||
'-5': '-1.25rem',
|
||||
'-6': '-1.5rem',
|
||||
'-8': '-2rem',
|
||||
'-10': '-2.5rem',
|
||||
'-12': '-3rem',
|
||||
'-16': '-4rem',
|
||||
'-20': '-5rem',
|
||||
'-24': '-6rem',
|
||||
'-32': '-8rem'
|
||||
},
|
||||
boxShadow: {
|
||||
default: '0 2px 4px 0 rgba(0,0,0,0.10)',
|
||||
md: '0 4px 8px 0 rgba(0,0,0,0.12), 0 2px 4px 0 rgba(0,0,0,0.08)',
|
||||
lg: '0 15px 30px 0 rgba(0,0,0,0.11), 0 5px 15px 0 rgba(0,0,0,0.08)',
|
||||
inner: 'inset 0 2px 4px 0 rgba(0,0,0,0.06)',
|
||||
outline: '0 0 0 3px rgba(52,144,220,0.5)',
|
||||
none: 'none',
|
||||
cloud: '0 0 5rem 5rem white',
|
||||
btn:
|
||||
'inset 0 -6px 12px 0 rgba(0,70,144,0.25), 0 4px 6px 0 rgba(34,0,51,0.04), 0 1px 10px 0 rgba(7,48,114,0.12), 0 2px 8px -1px rgba(14,13,26,0.08)'
|
||||
},
|
||||
opacity: {
|
||||
'0': '0',
|
||||
'25': '.25',
|
||||
'50': '.5',
|
||||
'75': '.75',
|
||||
'100': '1'
|
||||
},
|
||||
fill: {
|
||||
current: 'currentColor'
|
||||
},
|
||||
stroke: {
|
||||
current: 'currentColor'
|
||||
},
|
||||
|
||||
zIndex: {
|
||||
auto: 'auto',
|
||||
'0': 0,
|
||||
'10': 10,
|
||||
'20': 20,
|
||||
'30': 30,
|
||||
'40': 40,
|
||||
'50': 50
|
||||
}
|
||||
},
|
||||
|
||||
variants: {
|
||||
appearance: ['responsive'],
|
||||
backgroundAttachment: ['responsive'],
|
||||
backgroundColor: ['responsive', 'hover', 'focus'],
|
||||
backgroundPosition: ['responsive'],
|
||||
backgroundRepeat: ['responsive'],
|
||||
backgroundSize: ['responsive'],
|
||||
borderCollapse: [],
|
||||
borderColor: ['responsive', 'hover', 'focus'],
|
||||
borderRadius: ['responsive'],
|
||||
borderStyle: ['responsive'],
|
||||
borderWidth: ['responsive'],
|
||||
cursor: ['responsive'],
|
||||
display: ['responsive'],
|
||||
flexDirection: ['responsive'],
|
||||
flexWrap: ['responsive'],
|
||||
alignItems: ['responsive'],
|
||||
alignSelf: ['responsive'],
|
||||
alignContent: ['responsive'],
|
||||
justifyContent: ['responsive'],
|
||||
flex: ['responsive'],
|
||||
flexGrow: ['responsive'],
|
||||
flexShrink: ['responsive'],
|
||||
float: ['responsive'],
|
||||
fontFamily: ['responsive'],
|
||||
fontWeight: ['responsive', 'hover', 'focus'],
|
||||
height: ['responsive'],
|
||||
lineHeight: ['responsive'],
|
||||
listStylePosition: ['responsive'],
|
||||
listStyleType: ['responsive'],
|
||||
margin: ['responsive'],
|
||||
maxHeight: ['responsive'],
|
||||
maxWidth: ['responsive'],
|
||||
minHeight: ['responsive'],
|
||||
minWidth: ['responsive'],
|
||||
negativeMargin: ['responsive'],
|
||||
opacity: ['responsive', 'hover'],
|
||||
outline: ['focus'],
|
||||
overflow: ['responsive'],
|
||||
padding: ['responsive'],
|
||||
pointerEvents: ['responsive'],
|
||||
position: ['responsive'],
|
||||
inset: ['responsive'],
|
||||
resize: ['responsive'],
|
||||
boxShadow: ['responsive', 'hover', 'focus'],
|
||||
fill: [],
|
||||
stroke: [],
|
||||
tableLayout: ['responsive'],
|
||||
textAlign: ['responsive'],
|
||||
textColor: ['responsive', 'hover', 'focus'],
|
||||
fontSize: ['responsive'],
|
||||
fontStyle: ['responsive', 'hover', 'focus'],
|
||||
fontSmoothing: ['responsive', 'hover', 'focus'],
|
||||
textDecoration: ['responsive', 'hover', 'focus'],
|
||||
textTransform: ['responsive', 'hover', 'focus'],
|
||||
letterSpacing: ['responsive'],
|
||||
userSelect: ['responsive'],
|
||||
verticalAlign: ['responsive'],
|
||||
visibility: ['responsive'],
|
||||
whitespace: ['responsive'],
|
||||
wordBreak: ['responsive'],
|
||||
width: ['responsive'],
|
||||
zIndex: ['responsive']
|
||||
},
|
||||
corePlugins: {
|
||||
container: false
|
||||
},
|
||||
plugins: []
|
||||
};
|
||||
933
tailwind.js
933
tailwind.js
@@ -1,933 +0,0 @@
|
||||
/*
|
||||
|
||||
Tailwind - The Utility-First CSS Framework
|
||||
|
||||
A project by Adam Wathan (@adamwathan), Jonathan Reinink (@reinink),
|
||||
David Hemphill (@davidhemphill) and Steve Schoger (@steveschoger).
|
||||
|
||||
Welcome to the Tailwind config file. This is where you can customize
|
||||
Tailwind specifically for your project. Don't be intimidated by the
|
||||
length of this file. It's really just a big JavaScript object and
|
||||
we've done our very best to explain each section.
|
||||
|
||||
View the full documentation at https://tailwindcss.com.
|
||||
|
||||
|
||||
|-------------------------------------------------------------------------------
|
||||
| The default config
|
||||
|-------------------------------------------------------------------------------
|
||||
|
|
||||
| This variable contains the default Tailwind config. You don't have
|
||||
| to use it, but it can sometimes be helpful to have available. For
|
||||
| example, you may choose to merge your custom configuration
|
||||
| values with some of the Tailwind defaults.
|
||||
|
|
||||
*/
|
||||
|
||||
// let defaultConfig = require('tailwindcss/defaultConfig')()
|
||||
|
||||
/*
|
||||
|-------------------------------------------------------------------------------
|
||||
| Colors https://tailwindcss.com/docs/colors
|
||||
|-------------------------------------------------------------------------------
|
||||
|
|
||||
| Here you can specify the colors used in your project. To get you started,
|
||||
| we've provided a generous palette of great looking colors that are perfect
|
||||
| for prototyping, but don't hesitate to change them for your project. You
|
||||
| own these colors, nothing will break if you change everything about them.
|
||||
|
|
||||
| We've used literal color names ("red", "blue", etc.) for the default
|
||||
| palette, but if you'd rather use functional names like "primary" and
|
||||
| "secondary", or even a numeric scale like "100" and "200", go for it.
|
||||
|
|
||||
*/
|
||||
|
||||
const colors = {
|
||||
transparent: 'transparent',
|
||||
|
||||
black: '#22292f',
|
||||
'grey-darkest': '#4a4a4f',
|
||||
'grey-darker': '#606f7b',
|
||||
'grey-dark': '#8795a1',
|
||||
grey: '#B1B1B3',
|
||||
'grey-light': '#dae1e7',
|
||||
'grey-banner': '#f0f0f4',
|
||||
'grey-transparent': 'hsla(250, 13%, 9%, .2)',
|
||||
'grey-lighter': '#f1f5f8',
|
||||
'grey-lightest': '#F9F9FA',
|
||||
white: '#ffffff',
|
||||
|
||||
'red-darkest': '#3b0d0c',
|
||||
'red-darker': '#621b18',
|
||||
'red-dark': '#cc1f1a',
|
||||
red: '#e3342f',
|
||||
'red-light': '#ef5753',
|
||||
'red-lighter': '#f9acaa',
|
||||
'red-lightest': '#fcebea',
|
||||
|
||||
'orange-darkest': '#462a16',
|
||||
'orange-darker': '#613b1f',
|
||||
'orange-dark': '#de751f',
|
||||
orange: '#f6993f',
|
||||
'orange-light': '#faad63',
|
||||
'orange-lighter': '#fcd9b6',
|
||||
'orange-lightest': '#fff5eb',
|
||||
|
||||
'yellow-darkest': '#453411',
|
||||
'yellow-darker': '#684f1d',
|
||||
'yellow-dark': '#f2d024',
|
||||
yellow: '#ffed4a',
|
||||
'yellow-light': '#fff382',
|
||||
'yellow-lighter': '#fff9c2',
|
||||
'yellow-lightest': '#fcfbeb',
|
||||
|
||||
'green-darkest': '#003706',
|
||||
'green-darker': '#006504',
|
||||
'green-dark': '#058b00',
|
||||
green: '#12bc00',
|
||||
'green-light': '#51d88a',
|
||||
'green-lighter': '#a2f5bf',
|
||||
'green-lightest': '#e3fcec',
|
||||
|
||||
'teal-darkest': '#0d3331',
|
||||
'teal-darker': '#20504f',
|
||||
'teal-dark': '#38a89d',
|
||||
teal: '#4dc0b5',
|
||||
'teal-light': '#64d5ca',
|
||||
'teal-lighter': '#a0f0ed',
|
||||
'teal-lightest': '#e8fffe',
|
||||
|
||||
'blue-darkest': '#002275',
|
||||
'blue-darker': '#003eaa',
|
||||
'blue-dark': '#0060df',
|
||||
blue: '#0a84ff',
|
||||
'blue-light': '#6cb2eb',
|
||||
'blue-lighter': '#bcdefa',
|
||||
'blue-lightest': '#eff8ff',
|
||||
|
||||
'indigo-darkest': '#191e38',
|
||||
'indigo-darker': '#2f365f',
|
||||
'indigo-dark': '#5661b3',
|
||||
indigo: '#6574cd',
|
||||
'indigo-light': '#7886d7',
|
||||
'indigo-lighter': '#b2b7ff',
|
||||
'indigo-lightest': '#e6e8ff',
|
||||
|
||||
'purple-darkest': '#21183c',
|
||||
'purple-darker': '#382b5f',
|
||||
'purple-dark': '#794acf',
|
||||
purple: '#9561e2',
|
||||
'purple-light': '#a779e9',
|
||||
'purple-lighter': '#d6bbfc',
|
||||
'purple-lightest': '#f3ebff',
|
||||
|
||||
'pink-darkest': '#451225',
|
||||
'pink-darker': '#6f213f',
|
||||
'pink-dark': '#eb5286',
|
||||
pink: '#f66d9b',
|
||||
'pink-light': '#fa7ea8',
|
||||
'pink-lighter': '#ffbbca',
|
||||
'pink-lightest': '#ffebef',
|
||||
cloud: 'rgba(255, 255, 255, 0.8)',
|
||||
violet: 'hsl(258, 57%, 35%)'
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Colors https://tailwindcss.com/docs/colors
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| The color palette defined above is also assigned to the "colors" key of
|
||||
| your Tailwind config. This makes it easy to access them in your CSS
|
||||
| using Tailwind's config helper. For example:
|
||||
|
|
||||
| .error { color: config('colors.red') }
|
||||
|
|
||||
*/
|
||||
|
||||
colors: colors,
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Screens https://tailwindcss.com/docs/responsive-design
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Screens in Tailwind are translated to CSS media queries. They define the
|
||||
| responsive breakpoints for your project. By default Tailwind takes a
|
||||
| "mobile first" approach, where each screen size represents a minimum
|
||||
| viewport width. Feel free to have as few or as many screens as you
|
||||
| want, naming them in whatever way you'd prefer for your project.
|
||||
|
|
||||
| Tailwind also allows for more complex screen definitions, which can be
|
||||
| useful in certain situations. Be sure to see the full responsive
|
||||
| documentation for a complete list of options.
|
||||
|
|
||||
| Class name: .{screen}:{utility}
|
||||
|
|
||||
*/
|
||||
|
||||
screens: {
|
||||
sm: '576px',
|
||||
md: '768px',
|
||||
lg: '992px',
|
||||
xl: '1200px'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Fonts https://tailwindcss.com/docs/fonts
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your project's font stack, or font families.
|
||||
| Keep in mind that Tailwind doesn't actually load any fonts for you.
|
||||
| If you're using custom fonts you'll need to import them prior to
|
||||
| defining them here.
|
||||
|
|
||||
| By default we provide a native font stack that works remarkably well on
|
||||
| any device or OS you're using, since it just uses the default fonts
|
||||
| provided by the platform.
|
||||
|
|
||||
| Class name: .font-{name}
|
||||
|
|
||||
*/
|
||||
|
||||
fonts: {
|
||||
sans: [
|
||||
'Inter',
|
||||
'system-ui',
|
||||
'BlinkMacSystemFont',
|
||||
'-apple-system',
|
||||
'Segoe UI',
|
||||
'Roboto',
|
||||
'Oxygen',
|
||||
'Ubuntu',
|
||||
'Cantarell',
|
||||
'Fira Sans',
|
||||
'Droid Sans',
|
||||
'Helvetica Neue',
|
||||
'sans-serif'
|
||||
],
|
||||
serif: [
|
||||
'Constantia',
|
||||
'Lucida Bright',
|
||||
'Lucidabright',
|
||||
'Lucida Serif',
|
||||
'Lucida',
|
||||
'DejaVu Serif',
|
||||
'Bitstream Vera Serif',
|
||||
'Liberation Serif',
|
||||
'Georgia',
|
||||
'serif'
|
||||
],
|
||||
mono: [
|
||||
'Menlo',
|
||||
'Monaco',
|
||||
'Consolas',
|
||||
'Liberation Mono',
|
||||
'Courier New',
|
||||
'monospace'
|
||||
]
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Text sizes https://tailwindcss.com/docs/text-sizing
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your text sizes. Name these in whatever way
|
||||
| makes the most sense to you. We use size names by default, but
|
||||
| you're welcome to use a numeric scale or even something else
|
||||
| entirely.
|
||||
|
|
||||
| By default Tailwind uses the "rem" unit type for most measurements.
|
||||
| This allows you to set a root font size which all other sizes are
|
||||
| then based on. That said, you are free to use whatever units you
|
||||
| prefer, be it rems, ems, pixels or other.
|
||||
|
|
||||
| Class name: .text-{size}
|
||||
|
|
||||
*/
|
||||
|
||||
textSizes: {
|
||||
xs: '.75rem', // 12px
|
||||
sm: '.875rem', // 14px
|
||||
base: '1rem', // 16px
|
||||
lg: '1.125rem', // 18px
|
||||
xl: '1.25rem', // 20px
|
||||
'2xl': '1.5rem', // 24px
|
||||
'3xl': '1.875rem', // 30px
|
||||
'4xl': '2.25rem', // 36px
|
||||
'5xl': '3rem' // 48px
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Font weights https://tailwindcss.com/docs/font-weight
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your font weights. We've provided a list of
|
||||
| common font weight names with their respective numeric scale values
|
||||
| to get you started. It's unlikely that your project will require
|
||||
| all of these, so we recommend removing those you don't need.
|
||||
|
|
||||
| Class name: .font-{weight}
|
||||
|
|
||||
*/
|
||||
|
||||
fontWeights: {
|
||||
hairline: 100,
|
||||
thin: 200,
|
||||
light: 300,
|
||||
normal: 400,
|
||||
medium: 500,
|
||||
semibold: 600,
|
||||
bold: 700,
|
||||
extrabold: 800,
|
||||
black: 900
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Leading (line height) https://tailwindcss.com/docs/line-height
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your line height values, or as we call
|
||||
| them in Tailwind, leadings.
|
||||
|
|
||||
| Class name: .leading-{size}
|
||||
|
|
||||
*/
|
||||
|
||||
leading: {
|
||||
none: 1,
|
||||
tight: 1.25,
|
||||
normal: 1.5,
|
||||
loose: 1.75
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Tracking (letter spacing) https://tailwindcss.com/docs/letter-spacing
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your letter spacing values, or as we call
|
||||
| them in Tailwind, tracking.
|
||||
|
|
||||
| Class name: .tracking-{size}
|
||||
|
|
||||
*/
|
||||
|
||||
tracking: {
|
||||
tight: '-0.05em',
|
||||
normal: '0',
|
||||
wide: '0.05em'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Text colors https://tailwindcss.com/docs/text-color
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your text colors. By default these use the
|
||||
| color palette we defined above, however you're welcome to set these
|
||||
| independently if that makes sense for your project.
|
||||
|
|
||||
| Class name: .text-{color}
|
||||
|
|
||||
*/
|
||||
|
||||
textColors: colors,
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Background colors https://tailwindcss.com/docs/background-color
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your background colors. By default these use
|
||||
| the color palette we defined above, however you're welcome to set
|
||||
| these independently if that makes sense for your project.
|
||||
|
|
||||
| Class name: .bg-{color}
|
||||
|
|
||||
*/
|
||||
|
||||
backgroundColors: colors,
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Background sizes https://tailwindcss.com/docs/background-size
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your background sizes. We provide some common
|
||||
| values that are useful in most projects, but feel free to add other sizes
|
||||
| that are specific to your project here as well.
|
||||
|
|
||||
| Class name: .bg-{size}
|
||||
|
|
||||
*/
|
||||
|
||||
backgroundSize: {
|
||||
auto: 'auto',
|
||||
cover: 'cover',
|
||||
contain: 'contain'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Border widths https://tailwindcss.com/docs/border-width
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your border widths. Take note that border
|
||||
| widths require a special "default" value set as well. This is the
|
||||
| width that will be used when you do not specify a border width.
|
||||
|
|
||||
| Class name: .border{-side?}{-width?}
|
||||
|
|
||||
*/
|
||||
|
||||
borderWidths: {
|
||||
default: '1px',
|
||||
'0': '0',
|
||||
'2': '2px',
|
||||
'4': '4px',
|
||||
'8': '8px'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Border colors https://tailwindcss.com/docs/border-color
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your border colors. By default these use the
|
||||
| color palette we defined above, however you're welcome to set these
|
||||
| independently if that makes sense for your project.
|
||||
|
|
||||
| Take note that border colors require a special "default" value set
|
||||
| as well. This is the color that will be used when you do not
|
||||
| specify a border color.
|
||||
|
|
||||
| Class name: .border-{color}
|
||||
|
|
||||
*/
|
||||
|
||||
borderColors: global.Object.assign({ default: colors['grey-light'] }, colors),
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Border radius https://tailwindcss.com/docs/border-radius
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your border radius values. If a `default` radius
|
||||
| is provided, it will be made available as the non-suffixed `.rounded`
|
||||
| utility.
|
||||
|
|
||||
| If your scale includes a `0` value to reset already rounded corners, it's
|
||||
| a good idea to put it first so other values are able to override it.
|
||||
|
|
||||
| Class name: .rounded{-side?}{-size?}
|
||||
|
|
||||
*/
|
||||
|
||||
borderRadius: {
|
||||
none: '0',
|
||||
sm: '.125rem',
|
||||
default: '.25rem',
|
||||
lg: '.5rem',
|
||||
xl: '1rem',
|
||||
full: '9999px'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Width https://tailwindcss.com/docs/width
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your width utility sizes. These can be
|
||||
| percentage based, pixels, rems, or any other units. By default
|
||||
| we provide a sensible rem based numeric scale, a percentage
|
||||
| based fraction scale, plus some other common use-cases. You
|
||||
| can, of course, modify these values as needed.
|
||||
|
|
||||
|
|
||||
| It's also worth mentioning that Tailwind automatically escapes
|
||||
| invalid CSS class name characters, which allows you to have
|
||||
| awesome classes like .w-2/3.
|
||||
|
|
||||
| Class name: .w-{size}
|
||||
|
|
||||
*/
|
||||
|
||||
width: {
|
||||
auto: 'auto',
|
||||
px: '1px',
|
||||
'0': '0',
|
||||
'1': '0.25rem',
|
||||
'2': '0.5rem',
|
||||
'3': '0.75rem',
|
||||
'4': '1rem',
|
||||
'5': '1.25rem',
|
||||
'6': '1.5rem',
|
||||
'8': '2rem',
|
||||
'10': '2.5rem',
|
||||
'12': '3rem',
|
||||
'16': '4rem',
|
||||
'24': '6rem',
|
||||
'32': '8rem',
|
||||
'48': '12rem',
|
||||
'64': '16rem',
|
||||
'128': '32rem',
|
||||
'1/2': '50%',
|
||||
'1/3': '33.33333%',
|
||||
'2/3': '66.66667%',
|
||||
'1/4': '25%',
|
||||
'3/4': '75%',
|
||||
'1/5': '20%',
|
||||
'2/5': '40%',
|
||||
'3/5': '60%',
|
||||
'4/5': '80%',
|
||||
'1/6': '16.66667%',
|
||||
'5/6': '83.33333%',
|
||||
full: '100%',
|
||||
screen: '100vw'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Height https://tailwindcss.com/docs/height
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your height utility sizes. These can be
|
||||
| percentage based, pixels, rems, or any other units. By default
|
||||
| we provide a sensible rem based numeric scale plus some other
|
||||
| common use-cases. You can, of course, modify these values as
|
||||
| needed.
|
||||
|
|
||||
| Class name: .h-{size}
|
||||
|
|
||||
*/
|
||||
|
||||
height: {
|
||||
auto: 'auto',
|
||||
px: '1px',
|
||||
'0': '0',
|
||||
'1': '0.25rem',
|
||||
'2': '0.5rem',
|
||||
'3': '0.75rem',
|
||||
'4': '1rem',
|
||||
'5': '1.25rem',
|
||||
'6': '1.5rem',
|
||||
'8': '2rem',
|
||||
'10': '2.5rem',
|
||||
'12': '3rem',
|
||||
'16': '4rem',
|
||||
'24': '6rem',
|
||||
'32': '8rem',
|
||||
'48': '12rem',
|
||||
'64': '16rem',
|
||||
full: '100%',
|
||||
screen: '100vh'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Minimum width https://tailwindcss.com/docs/min-width
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your minimum width utility sizes. These can
|
||||
| be percentage based, pixels, rems, or any other units. We provide a
|
||||
| couple common use-cases by default. You can, of course, modify
|
||||
| these values as needed.
|
||||
|
|
||||
| Class name: .min-w-{size}
|
||||
|
|
||||
*/
|
||||
|
||||
minWidth: {
|
||||
'0': '0',
|
||||
full: '100%'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Minimum height https://tailwindcss.com/docs/min-height
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your minimum height utility sizes. These can
|
||||
| be percentage based, pixels, rems, or any other units. We provide a
|
||||
| few common use-cases by default. You can, of course, modify these
|
||||
| values as needed.
|
||||
|
|
||||
| Class name: .min-h-{size}
|
||||
|
|
||||
*/
|
||||
|
||||
minHeight: {
|
||||
'0': '0',
|
||||
full: '100%',
|
||||
screen: '100vh'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Maximum width https://tailwindcss.com/docs/max-width
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your maximum width utility sizes. These can
|
||||
| be percentage based, pixels, rems, or any other units. By default
|
||||
| we provide a sensible rem based scale and a "full width" size,
|
||||
| which is basically a reset utility. You can, of course,
|
||||
| modify these values as needed.
|
||||
|
|
||||
| Class name: .max-w-{size}
|
||||
|
|
||||
*/
|
||||
|
||||
maxWidth: {
|
||||
xs: '20rem',
|
||||
sm: '30rem',
|
||||
md: '40rem',
|
||||
lg: '50rem',
|
||||
xl: '60rem',
|
||||
'2xl': '70rem',
|
||||
'3xl': '80rem',
|
||||
'4xl': '90rem',
|
||||
'5xl': '100rem',
|
||||
full: '100%'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Maximum height https://tailwindcss.com/docs/max-height
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your maximum height utility sizes. These can
|
||||
| be percentage based, pixels, rems, or any other units. We provide a
|
||||
| couple common use-cases by default. You can, of course, modify
|
||||
| these values as needed.
|
||||
|
|
||||
| Class name: .max-h-{size}
|
||||
|
|
||||
*/
|
||||
|
||||
maxHeight: {
|
||||
full: '100%',
|
||||
'half-screen': '50vh',
|
||||
screen: '100vh'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Padding https://tailwindcss.com/docs/padding
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your padding utility sizes. These can be
|
||||
| percentage based, pixels, rems, or any other units. By default we
|
||||
| provide a sensible rem based numeric scale plus a couple other
|
||||
| common use-cases like "1px". You can, of course, modify these
|
||||
| values as needed.
|
||||
|
|
||||
| Class name: .p{side?}-{size}
|
||||
|
|
||||
*/
|
||||
|
||||
padding: {
|
||||
px: '1px',
|
||||
'0': '0',
|
||||
'1': '0.25rem',
|
||||
'2': '0.5rem',
|
||||
'3': '0.75rem',
|
||||
'4': '1rem',
|
||||
'5': '1.25rem',
|
||||
'6': '1.5rem',
|
||||
'8': '2rem',
|
||||
'10': '2.5rem',
|
||||
'12': '3rem',
|
||||
'16': '4rem',
|
||||
'20': '5rem',
|
||||
'24': '6rem',
|
||||
'32': '8rem'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Margin https://tailwindcss.com/docs/margin
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your margin utility sizes. These can be
|
||||
| percentage based, pixels, rems, or any other units. By default we
|
||||
| provide a sensible rem based numeric scale plus a couple other
|
||||
| common use-cases like "1px". You can, of course, modify these
|
||||
| values as needed.
|
||||
|
|
||||
| Class name: .m{side?}-{size}
|
||||
|
|
||||
*/
|
||||
|
||||
margin: {
|
||||
auto: 'auto',
|
||||
px: '1px',
|
||||
'0': '0',
|
||||
'1': '0.25rem',
|
||||
'2': '0.5rem',
|
||||
'3': '0.75rem',
|
||||
'4': '1rem',
|
||||
'5': '1.25rem',
|
||||
'6': '1.5rem',
|
||||
'8': '2rem',
|
||||
'10': '2.5rem',
|
||||
'12': '3rem',
|
||||
'16': '4rem',
|
||||
'20': '5rem',
|
||||
'24': '6rem',
|
||||
'32': '8rem'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Negative margin https://tailwindcss.com/docs/negative-margin
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your negative margin utility sizes. These can
|
||||
| be percentage based, pixels, rems, or any other units. By default we
|
||||
| provide matching values to the padding scale since these utilities
|
||||
| generally get used together. You can, of course, modify these
|
||||
| values as needed.
|
||||
|
|
||||
| Class name: .-m{side?}-{size}
|
||||
|
|
||||
*/
|
||||
|
||||
negativeMargin: {
|
||||
px: '1px',
|
||||
'0': '0',
|
||||
'1': '0.25rem',
|
||||
'2': '0.5rem',
|
||||
'3': '0.75rem',
|
||||
'4': '1rem',
|
||||
'5': '1.25rem',
|
||||
'6': '1.5rem',
|
||||
'8': '2rem',
|
||||
'10': '2.5rem',
|
||||
'12': '3rem',
|
||||
'16': '4rem',
|
||||
'20': '5rem',
|
||||
'24': '6rem',
|
||||
'32': '8rem'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Shadows https://tailwindcss.com/docs/shadows
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your shadow utilities. As you can see from
|
||||
| the defaults we provide, it's possible to apply multiple shadows
|
||||
| per utility using comma separation.
|
||||
|
|
||||
| If a `default` shadow is provided, it will be made available as the non-
|
||||
| suffixed `.shadow` utility.
|
||||
|
|
||||
| Class name: .shadow-{size?}
|
||||
|
|
||||
*/
|
||||
|
||||
shadows: {
|
||||
default: '0 2px 4px 0 rgba(0,0,0,0.10)',
|
||||
md: '0 4px 8px 0 rgba(0,0,0,0.12), 0 2px 4px 0 rgba(0,0,0,0.08)',
|
||||
lg: '0 15px 30px 0 rgba(0,0,0,0.11), 0 5px 15px 0 rgba(0,0,0,0.08)',
|
||||
inner: 'inset 0 2px 4px 0 rgba(0,0,0,0.06)',
|
||||
outline: '0 0 0 3px rgba(52,144,220,0.5)',
|
||||
none: 'none',
|
||||
cloud: '0 0 5rem 5rem white',
|
||||
btn:
|
||||
'inset 0 -6px 12px 0 rgba(0,70,144,0.25), 0 4px 6px 0 rgba(34,0,51,0.04), 0 1px 10px 0 rgba(7,48,114,0.12), 0 2px 8px -1px rgba(14,13,26,0.08)'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Z-index https://tailwindcss.com/docs/z-index
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your z-index utility values. By default we
|
||||
| provide a sensible numeric scale. You can, of course, modify these
|
||||
| values as needed.
|
||||
|
|
||||
| Class name: .z-{index}
|
||||
|
|
||||
*/
|
||||
|
||||
zIndex: {
|
||||
auto: 'auto',
|
||||
'0': 0,
|
||||
'10': 10,
|
||||
'20': 20,
|
||||
'30': 30,
|
||||
'40': 40,
|
||||
'50': 50
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Opacity https://tailwindcss.com/docs/opacity
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your opacity utility values. By default we
|
||||
| provide a sensible numeric scale. You can, of course, modify these
|
||||
| values as needed.
|
||||
|
|
||||
| Class name: .opacity-{name}
|
||||
|
|
||||
*/
|
||||
|
||||
opacity: {
|
||||
'0': '0',
|
||||
'25': '.25',
|
||||
'50': '.5',
|
||||
'75': '.75',
|
||||
'100': '1'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| SVG fill https://tailwindcss.com/docs/svg
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your SVG fill colors. By default we just provide
|
||||
| `fill-current` which sets the fill to the current text color. This lets you
|
||||
| specify a fill color using existing text color utilities and helps keep the
|
||||
| generated CSS file size down.
|
||||
|
|
||||
| Class name: .fill-{name}
|
||||
|
|
||||
*/
|
||||
|
||||
svgFill: {
|
||||
current: 'currentColor'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| SVG stroke https://tailwindcss.com/docs/svg
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you define your SVG stroke colors. By default we just provide
|
||||
| `stroke-current` which sets the stroke to the current text color. This lets
|
||||
| you specify a stroke color using existing text color utilities and helps
|
||||
| keep the generated CSS file size down.
|
||||
|
|
||||
| Class name: .stroke-{name}
|
||||
|
|
||||
*/
|
||||
|
||||
svgStroke: {
|
||||
current: 'currentColor'
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Modules https://tailwindcss.com/docs/configuration#modules
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you control which modules are generated and what variants are
|
||||
| generated for each of those modules.
|
||||
|
|
||||
| Currently supported variants:
|
||||
| - responsive
|
||||
| - hover
|
||||
| - focus
|
||||
| - active
|
||||
| - group-hover
|
||||
|
|
||||
| To disable a module completely, use `false` instead of an array.
|
||||
|
|
||||
*/
|
||||
|
||||
modules: {
|
||||
appearance: ['responsive'],
|
||||
backgroundAttachment: ['responsive'],
|
||||
backgroundColors: ['responsive', 'hover', 'focus'],
|
||||
backgroundPosition: ['responsive'],
|
||||
backgroundRepeat: ['responsive'],
|
||||
backgroundSize: ['responsive'],
|
||||
borderCollapse: [],
|
||||
borderColors: ['responsive', 'hover', 'focus'],
|
||||
borderRadius: ['responsive'],
|
||||
borderStyle: ['responsive'],
|
||||
borderWidths: ['responsive'],
|
||||
cursor: ['responsive'],
|
||||
display: ['responsive'],
|
||||
flexbox: ['responsive'],
|
||||
float: ['responsive'],
|
||||
fonts: ['responsive'],
|
||||
fontWeights: ['responsive', 'hover', 'focus'],
|
||||
height: ['responsive'],
|
||||
leading: ['responsive'],
|
||||
lists: ['responsive'],
|
||||
margin: ['responsive'],
|
||||
maxHeight: ['responsive'],
|
||||
maxWidth: ['responsive'],
|
||||
minHeight: ['responsive'],
|
||||
minWidth: ['responsive'],
|
||||
negativeMargin: ['responsive'],
|
||||
opacity: ['responsive', 'hover'],
|
||||
outline: ['focus'],
|
||||
overflow: ['responsive'],
|
||||
padding: ['responsive'],
|
||||
pointerEvents: ['responsive'],
|
||||
position: ['responsive'],
|
||||
resize: ['responsive'],
|
||||
shadows: ['responsive', 'hover', 'focus'],
|
||||
svgFill: [],
|
||||
svgStroke: [],
|
||||
tableLayout: ['responsive'],
|
||||
textAlign: ['responsive'],
|
||||
textColors: ['responsive', 'hover', 'focus'],
|
||||
textSizes: ['responsive'],
|
||||
textStyle: ['responsive', 'hover', 'focus'],
|
||||
tracking: ['responsive'],
|
||||
userSelect: ['responsive'],
|
||||
verticalAlign: ['responsive'],
|
||||
visibility: ['responsive'],
|
||||
whitespace: ['responsive'],
|
||||
width: ['responsive'],
|
||||
zIndex: ['responsive']
|
||||
},
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Plugins https://tailwindcss.com/docs/plugins
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you can register any plugins you'd like to use in your
|
||||
| project. Tailwind's built-in `container` plugin is enabled by default to
|
||||
| give you a Bootstrap-style responsive container component out of the box.
|
||||
|
|
||||
| Be sure to view the complete plugin documentation to learn more about how
|
||||
| the plugin system works.
|
||||
|
|
||||
*/
|
||||
|
||||
plugins: [
|
||||
require('tailwindcss/plugins/container')({
|
||||
// center: true,
|
||||
// padding: '1rem',
|
||||
})
|
||||
],
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------------------------------
|
||||
| Advanced Options https://tailwindcss.com/docs/configuration#options
|
||||
|-----------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you can tweak advanced configuration options. We recommend
|
||||
| leaving these options alone unless you absolutely need to change them.
|
||||
|
|
||||
*/
|
||||
|
||||
options: {
|
||||
prefix: '',
|
||||
important: false,
|
||||
separator: ':'
|
||||
}
|
||||
};
|
||||
@@ -19,5 +19,7 @@ rules:
|
||||
mocha/no-pending-tests: error
|
||||
mocha/no-return-and-callback: warn
|
||||
mocha/no-skipped-tests: error
|
||||
mocha/no-setup-in-describe: off
|
||||
mocha/no-hooks-for-single-case: off
|
||||
|
||||
no-console: off # ¯\_(ツ)_/¯
|
||||
|
||||
@@ -6,7 +6,7 @@ module.exports = {
|
||||
const webpack = require('webpack');
|
||||
const middleware = require('webpack-dev-middleware');
|
||||
const express = require('express');
|
||||
const expressWs = require('express-ws');
|
||||
const expressWs = require('@dannycoates/express-ws');
|
||||
const assets = require('../common/assets');
|
||||
const routes = require('../server/routes');
|
||||
const tests = require('./frontend/routes');
|
||||
@@ -18,8 +18,8 @@ module.exports = {
|
||||
app.use(wpm);
|
||||
assets.setMiddleware(wpm);
|
||||
expressWs(app, null, { perMessageDeflate: false });
|
||||
app.ws('/api/ws', require('../server/routes/ws'));
|
||||
routes(app);
|
||||
app.ws('/api/ws', require('../server/routes/ws'));
|
||||
tests(app);
|
||||
wpm.waitUntilValid(() => {
|
||||
server = app.listen(8000, resolve);
|
||||
|
||||
@@ -103,8 +103,7 @@ const web = {
|
||||
__dirname,
|
||||
'node_modules/@dannycoates/webcrypto-liner'
|
||||
),
|
||||
path.resolve(__dirname, 'node_modules/fluent'),
|
||||
path.resolve(__dirname, 'node_modules/fluent-intl-polyfill'),
|
||||
path.resolve(__dirname, 'node_modules/@fluent'),
|
||||
path.resolve(__dirname, 'node_modules/intl-pluralrules')
|
||||
],
|
||||
options: webJsOptions
|
||||
@@ -114,7 +113,8 @@ const web = {
|
||||
include: [path.resolve(__dirname, 'node_modules')],
|
||||
exclude: [
|
||||
path.resolve(__dirname, 'node_modules/crc'),
|
||||
path.resolve(__dirname, 'node_modules/fluent'),
|
||||
path.resolve(__dirname, 'node_modules/@fluent'),
|
||||
path.resolve(__dirname, 'node_modules/@sentry'),
|
||||
path.resolve(__dirname, 'node_modules/tslib'),
|
||||
path.resolve(__dirname, 'node_modules/webcrypto-core')
|
||||
],
|
||||
@@ -216,6 +216,7 @@ const web = {
|
||||
|
||||
module.exports = (env, argv) => {
|
||||
const mode = argv.mode || 'production';
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`mode: ${mode}`);
|
||||
process.env.NODE_ENV = web.mode = serviceWorker.mode = mode;
|
||||
if (mode === 'development') {
|
||||
|
||||
Reference in New Issue
Block a user