Compare commits

..

1 Commits

Author SHA1 Message Date
akwizgran
934997ed91 Check for partial setup of clients due to feature flags reverting. 2023-01-31 11:23:19 +00:00
146 changed files with 1227 additions and 3766 deletions

View File

@@ -83,8 +83,7 @@ android test:
test_reproducible: test_reproducible:
stage: check_reproducibility stage: check_reproducibility
script: script:
- "curl -X POST -F token=${RELEASE_CHECK_TOKEN} -F ref=master -F variables[APP]='briar' -F variables[RELEASE_TAG]=${CI_COMMIT_REF_NAME} https://code.briarproject.org/api/v4/projects/61/trigger/pipeline" - "curl -X POST -F token=${RELEASE_CHECK_TOKEN} -F ref=master -F variables[RELEASE_TAG]=${CI_COMMIT_REF_NAME} https://code.briarproject.org/api/v4/projects/61/trigger/pipeline"
- "curl -X POST -F token=${RELEASE_JAR_CHECK_TOKEN} -F ref=main -F variables[APP]='briar-headless' -F variables[RELEASE_TAG]=${CI_COMMIT_REF_NAME} https://code.briarproject.org/api/v4/projects/307/trigger/pipeline"
only: only:
- tags - tags

View File

@@ -13,8 +13,8 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 31 targetSdkVersion 31
versionCode 10423 versionCode 10420
versionName "1.4.23" versionName "1.4.20"
consumerProguardFiles 'proguard-rules.txt' consumerProguardFiles 'proguard-rules.txt'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -71,7 +71,7 @@ def torLibsDir = 'src/main/jniLibs'
task cleanTorBinaries { task cleanTorBinaries {
outputs.dir torLibsDir outputs.dir torLibsDir
doLast { doLast {
delete fileTree(torLibsDir) delete fileTree(torLibsDir) { include '**/*.so' }
} }
} }
@@ -80,9 +80,34 @@ clean.dependsOn cleanTorBinaries
task unpackTorBinaries { task unpackTorBinaries {
outputs.dir torLibsDir outputs.dir torLibsDir
doLast { doLast {
copy { configurations.tor.each { outer ->
from configurations.tor.collect { zipTree(it) } zipTree(outer).each { inner ->
into torLibsDir if (inner.name.endsWith('_arm_pie.zip')) {
copy {
from zipTree(inner)
into torLibsDir
rename '(.*)', 'armeabi-v7a/lib$1.so'
}
} else if (inner.name.endsWith('_arm64_pie.zip')) {
copy {
from zipTree(inner)
into torLibsDir
rename '(.*)', 'arm64-v8a/lib$1.so'
}
} else if (inner.name.endsWith('_x86_pie.zip')) {
copy {
from zipTree(inner)
into torLibsDir
rename '(.*)', 'x86/lib$1.so'
}
} else if (inner.name.endsWith('_x86_64_pie.zip')) {
copy {
from zipTree(inner)
into torLibsDir
rename '(.*)', 'x86_64/lib$1.so'
}
}
}
} }
} }
dependsOn cleanTorBinaries dependsOn cleanTorBinaries

View File

@@ -33,10 +33,8 @@ class AndroidBluetoothTransportConnection
super(plugin); super(plugin);
this.connectionLimiter = connectionLimiter; this.connectionLimiter = connectionLimiter;
this.socket = socket; this.socket = socket;
InputStream socketIn = socket.getInputStream(); in = timeoutMonitor.createTimeoutInputStream(
if (socketIn == null) throw new IOException(); socket.getInputStream(), plugin.getMaxIdleTime() * 2);
in = timeoutMonitor.createTimeoutInputStream(socketIn,
plugin.getMaxIdleTime() * 2L);
wakeLock = wakeLockManager.createWakeLock("BluetoothConnection"); wakeLock = wakeLockManager.createWakeLock("BluetoothConnection");
wakeLock.acquire(); wakeLock.acquire();
String address = socket.getRemoteDevice().getAddress(); String address = socket.getRemoteDevice().getAddress();
@@ -50,9 +48,7 @@ class AndroidBluetoothTransportConnection
@Override @Override
protected OutputStream getOutputStream() throws IOException { protected OutputStream getOutputStream() throws IOException {
OutputStream socketOut = socket.getOutputStream(); return socket.getOutputStream();
if (socketOut == null) throw new IOException();
return socketOut;
} }
@Override @Override

View File

@@ -24,8 +24,8 @@ dependencyVerification {
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0', 'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd', 'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047', 'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
'org.briarproject:obfs4proxy-android:0.0.14:obfs4proxy-android-0.0.14.jar:ad9b1ee4757b05867a19e993147bbb018bddd1f26ce3da746d5f037d5991a8c8', 'org.briarproject:obfs4proxy-android:0.0.14-tor1:obfs4proxy-android-0.0.14-tor1.jar:8b08068778b133484b17956d8f7a7710739c33f671a26a68156f4d34e6f28c30',
'org.briarproject:snowflake-android:2.5.1:snowflake-android-2.5.1.jar:88ec81c17b1b6fa884d06839dec0330e328b45c89f88c970a213ce91ca8eac87', 'org.briarproject:snowflake-android:2.3.1:snowflake-android-2.3.1.jar:1f83c9a070f87b7074af13627709a8b5aced5460104be7166af736b1bb73c293',
'org.briarproject:tor-android:0.4.7.13:tor-android-0.4.7.13.jar:7852aab7d2298b80878c7719f34ce665725b494d673ecf2e6f9e697564638cc6', 'org.briarproject:tor-android:0.4.7.13:tor-android-0.4.7.13.jar:7852aab7d2298b80878c7719f34ce665725b494d673ecf2e6f9e697564638cc6',
'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a', 'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a',
'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb', 'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb',

View File

@@ -16,7 +16,6 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE; import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
@Immutable @Immutable
@@ -24,24 +23,17 @@ import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOC
public abstract class BdfMessageValidator implements MessageValidator { public abstract class BdfMessageValidator implements MessageValidator {
protected static final Logger LOG = protected static final Logger LOG =
getLogger(BdfMessageValidator.class.getName()); Logger.getLogger(BdfMessageValidator.class.getName());
protected final ClientHelper clientHelper; protected final ClientHelper clientHelper;
protected final MetadataEncoder metadataEncoder; protected final MetadataEncoder metadataEncoder;
protected final Clock clock; protected final Clock clock;
protected final boolean canonical;
protected BdfMessageValidator(ClientHelper clientHelper,
MetadataEncoder metadataEncoder, Clock clock, boolean canonical) {
this.clientHelper = clientHelper;
this.metadataEncoder = metadataEncoder;
this.clock = clock;
this.canonical = canonical;
}
protected BdfMessageValidator(ClientHelper clientHelper, protected BdfMessageValidator(ClientHelper clientHelper,
MetadataEncoder metadataEncoder, Clock clock) { MetadataEncoder metadataEncoder, Clock clock) {
this(clientHelper, metadataEncoder, clock, true); this.clientHelper = clientHelper;
this.metadataEncoder = metadataEncoder;
this.clock = clock;
} }
protected abstract BdfMessageContext validateMessage(Message m, Group g, protected abstract BdfMessageContext validateMessage(Message m, Group g,
@@ -57,7 +49,7 @@ public abstract class BdfMessageValidator implements MessageValidator {
"Timestamp is too far in the future"); "Timestamp is too far in the future");
} }
try { try {
BdfList bodyList = clientHelper.toList(m, canonical); BdfList bodyList = clientHelper.toList(m.getBody());
BdfMessageContext result = validateMessage(m, g, bodyList); BdfMessageContext result = validateMessage(m, g, bodyList);
Metadata meta = metadataEncoder.encode(result.getDictionary()); Metadata meta = metadataEncoder.encode(result.getDictionary());
return new MessageContext(meta, result.getDependencies()); return new MessageContext(meta, result.getDependencies());

View File

@@ -49,9 +49,6 @@ public interface ClientHelper {
BdfList getMessageAsList(Transaction txn, MessageId m) throws DbException, BdfList getMessageAsList(Transaction txn, MessageId m) throws DbException,
FormatException; FormatException;
BdfList getMessageAsList(Transaction txn, MessageId m, boolean canonical)
throws DbException, FormatException;
BdfDictionary getGroupMetadataAsDictionary(GroupId g) throws DbException, BdfDictionary getGroupMetadataAsDictionary(GroupId g) throws DbException,
FormatException; FormatException;
@@ -109,8 +106,6 @@ public interface ClientHelper {
BdfList toList(Message m) throws FormatException; BdfList toList(Message m) throws FormatException;
BdfList toList(Message m, boolean canonical) throws FormatException;
BdfList toList(Author a); BdfList toList(Author a);
byte[] sign(String label, BdfList toSign, PrivateKey privateKey) byte[] sign(String label, BdfList toSign, PrivateKey privateKey)

View File

@@ -11,7 +11,7 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe; import javax.annotation.concurrent.NotThreadSafe;
@NotThreadSafe @NotThreadSafe
public final class BdfDictionary extends TreeMap<String, Object> { public class BdfDictionary extends TreeMap<String, Object> {
public static final Object NULL_VALUE = new Object(); public static final Object NULL_VALUE = new Object();
@@ -39,9 +39,9 @@ public final class BdfDictionary extends TreeMap<String, Object> {
} }
public Boolean getBoolean(String key) throws FormatException { public Boolean getBoolean(String key) throws FormatException {
Boolean value = getOptionalBoolean(key); Object o = get(key);
if (value == null) throw new FormatException(); if (o instanceof Boolean) return (Boolean) o;
return value; throw new FormatException();
} }
@Nullable @Nullable
@@ -52,16 +52,19 @@ public final class BdfDictionary extends TreeMap<String, Object> {
throw new FormatException(); throw new FormatException();
} }
public Boolean getBoolean(String key, Boolean defaultValue) public Boolean getBoolean(String key, Boolean defaultValue) {
throws FormatException { Object o = get(key);
Boolean value = getOptionalBoolean(key); if (o instanceof Boolean) return (Boolean) o;
return value == null ? defaultValue : value; return defaultValue;
} }
public Long getLong(String key) throws FormatException { public Long getLong(String key) throws FormatException {
Long value = getOptionalLong(key); Object o = get(key);
if (value == null) throw new FormatException(); if (o instanceof Long) return (Long) o;
return value; if (o instanceof Integer) return ((Integer) o).longValue();
if (o instanceof Short) return ((Short) o).longValue();
if (o instanceof Byte) return ((Byte) o).longValue();
throw new FormatException();
} }
@Nullable @Nullable
@@ -75,37 +78,20 @@ public final class BdfDictionary extends TreeMap<String, Object> {
throw new FormatException(); throw new FormatException();
} }
public Long getLong(String key, Long defaultValue) throws FormatException { public Long getLong(String key, Long defaultValue) {
Long value = getOptionalLong(key); Object o = get(key);
return value == null ? defaultValue : value; if (o instanceof Long) return (Long) o;
} if (o instanceof Integer) return ((Integer) o).longValue();
if (o instanceof Short) return ((Short) o).longValue();
public Integer getInt(String key) throws FormatException { if (o instanceof Byte) return ((Byte) o).longValue();
Integer value = getOptionalInt(key); return defaultValue;
if (value == null) throw new FormatException();
return value;
}
@Nullable
public Integer getOptionalInt(String key) throws FormatException {
Long value = getOptionalLong(key);
if (value == null) return null;
if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
throw new FormatException();
}
return value.intValue();
}
public Integer getInt(String key, Integer defaultValue)
throws FormatException {
Integer value = getOptionalInt(key);
return value == null ? defaultValue : value;
} }
public Double getDouble(String key) throws FormatException { public Double getDouble(String key) throws FormatException {
Double value = getOptionalDouble(key); Object o = get(key);
if (value == null) throw new FormatException(); if (o instanceof Double) return (Double) o;
return value; if (o instanceof Float) return ((Float) o).doubleValue();
throw new FormatException();
} }
@Nullable @Nullable
@@ -117,16 +103,17 @@ public final class BdfDictionary extends TreeMap<String, Object> {
throw new FormatException(); throw new FormatException();
} }
public Double getDouble(String key, Double defaultValue) public Double getDouble(String key, Double defaultValue) {
throws FormatException { Object o = get(key);
Double value = getOptionalDouble(key); if (o instanceof Double) return (Double) o;
return value == null ? defaultValue : value; if (o instanceof Float) return ((Float) o).doubleValue();
return defaultValue;
} }
public String getString(String key) throws FormatException { public String getString(String key) throws FormatException {
String value = getOptionalString(key); Object o = get(key);
if (value == null) throw new FormatException(); if (o instanceof String) return (String) o;
return value; throw new FormatException();
} }
@Nullable @Nullable
@@ -137,16 +124,17 @@ public final class BdfDictionary extends TreeMap<String, Object> {
throw new FormatException(); throw new FormatException();
} }
public String getString(String key, String defaultValue) public String getString(String key, String defaultValue) {
throws FormatException { Object o = get(key);
String value = getOptionalString(key); if (o instanceof String) return (String) o;
return value == null ? defaultValue : value; return defaultValue;
} }
public byte[] getRaw(String key) throws FormatException { public byte[] getRaw(String key) throws FormatException {
byte[] value = getOptionalRaw(key); Object o = get(key);
if (value == null) throw new FormatException(); if (o instanceof byte[]) return (byte[]) o;
return value; if (o instanceof Bytes) return ((Bytes) o).getBytes();
throw new FormatException();
} }
@Nullable @Nullable
@@ -158,16 +146,17 @@ public final class BdfDictionary extends TreeMap<String, Object> {
throw new FormatException(); throw new FormatException();
} }
public byte[] getRaw(String key, byte[] defaultValue) public byte[] getRaw(String key, byte[] defaultValue) {
throws FormatException { Object o = get(key);
byte[] value = getOptionalRaw(key); if (o instanceof byte[]) return (byte[]) o;
return value == null ? defaultValue : value; if (o instanceof Bytes) return ((Bytes) o).getBytes();
return defaultValue;
} }
public BdfList getList(String key) throws FormatException { public BdfList getList(String key) throws FormatException {
BdfList value = getOptionalList(key); Object o = get(key);
if (value == null) throw new FormatException(); if (o instanceof BdfList) return (BdfList) o;
return value; throw new FormatException();
} }
@Nullable @Nullable
@@ -178,16 +167,16 @@ public final class BdfDictionary extends TreeMap<String, Object> {
throw new FormatException(); throw new FormatException();
} }
public BdfList getList(String key, BdfList defaultValue) public BdfList getList(String key, BdfList defaultValue) {
throws FormatException { Object o = get(key);
BdfList value = getOptionalList(key); if (o instanceof BdfList) return (BdfList) o;
return value == null ? defaultValue : value; return defaultValue;
} }
public BdfDictionary getDictionary(String key) throws FormatException { public BdfDictionary getDictionary(String key) throws FormatException {
BdfDictionary value = getOptionalDictionary(key); Object o = get(key);
if (value == null) throw new FormatException(); if (o instanceof BdfDictionary) return (BdfDictionary) o;
return value; throw new FormatException();
} }
@Nullable @Nullable
@@ -199,9 +188,9 @@ public final class BdfDictionary extends TreeMap<String, Object> {
throw new FormatException(); throw new FormatException();
} }
public BdfDictionary getDictionary(String key, BdfDictionary defaultValue) public BdfDictionary getDictionary(String key, BdfDictionary defaultValue) {
throws FormatException { Object o = get(key);
BdfDictionary value = getOptionalDictionary(key); if (o instanceof BdfDictionary) return (BdfDictionary) o;
return value == null ? defaultValue : value; return defaultValue;
} }
} }

View File

@@ -13,7 +13,7 @@ import javax.annotation.concurrent.NotThreadSafe;
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE; import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
@NotThreadSafe @NotThreadSafe
public final class BdfList extends ArrayList<Object> { public class BdfList extends ArrayList<Object> {
/** /**
* Factory method for constructing lists inline. * Factory method for constructing lists inline.
@@ -33,15 +33,15 @@ public final class BdfList extends ArrayList<Object> {
super(items); super(items);
} }
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private boolean isInRange(int index) { private boolean isInRange(int index) {
return index >= 0 && index < size(); return index >= 0 && index < size();
} }
public Boolean getBoolean(int index) throws FormatException { public Boolean getBoolean(int index) throws FormatException {
Boolean value = getOptionalBoolean(index); if (!isInRange(index)) throw new FormatException();
if (value == null) throw new FormatException(); Object o = get(index);
return value; if (o instanceof Boolean) return (Boolean) o;
throw new FormatException();
} }
@Nullable @Nullable
@@ -53,16 +53,21 @@ public final class BdfList extends ArrayList<Object> {
throw new FormatException(); throw new FormatException();
} }
public Boolean getBoolean(int index, Boolean defaultValue) public Boolean getBoolean(int index, Boolean defaultValue) {
throws FormatException { if (!isInRange(index)) return defaultValue;
Boolean value = getOptionalBoolean(index); Object o = get(index);
return value == null ? defaultValue : value; if (o instanceof Boolean) return (Boolean) o;
return defaultValue;
} }
public Long getLong(int index) throws FormatException { public Long getLong(int index) throws FormatException {
Long value = getOptionalLong(index); if (!isInRange(index)) throw new FormatException();
if (value == null) throw new FormatException(); Object o = get(index);
return value; if (o instanceof Long) return (Long) o;
if (o instanceof Integer) return ((Integer) o).longValue();
if (o instanceof Short) return ((Short) o).longValue();
if (o instanceof Byte) return ((Byte) o).longValue();
throw new FormatException();
} }
@Nullable @Nullable
@@ -77,37 +82,22 @@ public final class BdfList extends ArrayList<Object> {
throw new FormatException(); throw new FormatException();
} }
public Long getLong(int index, Long defaultValue) throws FormatException { public Long getLong(int index, Long defaultValue) {
Long value = getOptionalLong(index); if (!isInRange(index)) return defaultValue;
return value == null ? defaultValue : value; Object o = get(index);
} if (o instanceof Long) return (Long) o;
if (o instanceof Integer) return ((Integer) o).longValue();
public Integer getInt(int index) throws FormatException { if (o instanceof Short) return ((Short) o).longValue();
Integer value = getOptionalInt(index); if (o instanceof Byte) return ((Byte) o).longValue();
if (value == null) throw new FormatException(); return defaultValue;
return value;
}
@Nullable
public Integer getOptionalInt(int index) throws FormatException {
Long value = getOptionalLong(index);
if (value == null) return null;
if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
throw new FormatException();
}
return value.intValue();
}
public Integer getInt(int index, Integer defaultValue)
throws FormatException {
Integer value = getOptionalInt(index);
return value == null ? defaultValue : value;
} }
public Double getDouble(int index) throws FormatException { public Double getDouble(int index) throws FormatException {
Double value = getOptionalDouble(index); if (!isInRange(index)) throw new FormatException();
if (value == null) throw new FormatException(); Object o = get(index);
return value; if (o instanceof Double) return (Double) o;
if (o instanceof Float) return ((Float) o).doubleValue();
throw new FormatException();
} }
@Nullable @Nullable
@@ -120,16 +110,19 @@ public final class BdfList extends ArrayList<Object> {
throw new FormatException(); throw new FormatException();
} }
public Double getDouble(int index, Double defaultValue) public Double getDouble(int index, Double defaultValue) {
throws FormatException { if (!isInRange(index)) return defaultValue;
Double value = getOptionalDouble(index); Object o = get(index);
return value == null ? defaultValue : value; if (o instanceof Double) return (Double) o;
if (o instanceof Float) return ((Float) o).doubleValue();
return defaultValue;
} }
public String getString(int index) throws FormatException { public String getString(int index) throws FormatException {
String value = getOptionalString(index); if (!isInRange(index)) throw new FormatException();
if (value == null) throw new FormatException(); Object o = get(index);
return value; if (o instanceof String) return (String) o;
throw new FormatException();
} }
@Nullable @Nullable
@@ -141,16 +134,19 @@ public final class BdfList extends ArrayList<Object> {
throw new FormatException(); throw new FormatException();
} }
public String getString(int index, String defaultValue) public String getString(int index, String defaultValue) {
throws FormatException { if (!isInRange(index)) return defaultValue;
String value = getOptionalString(index); Object o = get(index);
return value == null ? defaultValue : value; if (o instanceof String) return (String) o;
return defaultValue;
} }
public byte[] getRaw(int index) throws FormatException { public byte[] getRaw(int index) throws FormatException {
byte[] value = getOptionalRaw(index); if (!isInRange(index)) throw new FormatException();
if (value == null) throw new FormatException(); Object o = get(index);
return value; if (o instanceof byte[]) return (byte[]) o;
if (o instanceof Bytes) return ((Bytes) o).getBytes();
throw new FormatException();
} }
@Nullable @Nullable
@@ -163,16 +159,19 @@ public final class BdfList extends ArrayList<Object> {
throw new FormatException(); throw new FormatException();
} }
public byte[] getRaw(int index, byte[] defaultValue) public byte[] getRaw(int index, byte[] defaultValue) {
throws FormatException { if (!isInRange(index)) return defaultValue;
byte[] value = getOptionalRaw(index); Object o = get(index);
return value == null ? defaultValue : value; if (o instanceof byte[]) return (byte[]) o;
if (o instanceof Bytes) return ((Bytes) o).getBytes();
return defaultValue;
} }
public BdfList getList(int index) throws FormatException { public BdfList getList(int index) throws FormatException {
BdfList value = getOptionalList(index); if (!isInRange(index)) throw new FormatException();
if (value == null) throw new FormatException(); Object o = get(index);
return value; if (o instanceof BdfList) return (BdfList) o;
throw new FormatException();
} }
@Nullable @Nullable
@@ -184,16 +183,18 @@ public final class BdfList extends ArrayList<Object> {
throw new FormatException(); throw new FormatException();
} }
public BdfList getList(int index, BdfList defaultValue) public BdfList getList(int index, BdfList defaultValue) {
throws FormatException { if (!isInRange(index)) return defaultValue;
BdfList value = getOptionalList(index); Object o = get(index);
return value == null ? defaultValue : value; if (o instanceof BdfList) return (BdfList) o;
return defaultValue;
} }
public BdfDictionary getDictionary(int index) throws FormatException { public BdfDictionary getDictionary(int index) throws FormatException {
BdfDictionary value = getOptionalDictionary(index); if (!isInRange(index)) throw new FormatException();
if (value == null) throw new FormatException(); Object o = get(index);
return value; if (o instanceof BdfDictionary) return (BdfDictionary) o;
throw new FormatException();
} }
@Nullable @Nullable
@@ -206,9 +207,10 @@ public final class BdfList extends ArrayList<Object> {
throw new FormatException(); throw new FormatException();
} }
public BdfDictionary getDictionary(int index, BdfDictionary defaultValue) public BdfDictionary getDictionary(int index, BdfDictionary defaultValue) {
throws FormatException { if (!isInRange(index)) return defaultValue;
BdfDictionary value = getOptionalDictionary(index); Object o = get(index);
return value == null ? defaultValue : value; if (o instanceof BdfDictionary) return (BdfDictionary) o;
return defaultValue;
} }
} }

View File

@@ -32,12 +32,6 @@ public interface BdfReader {
void skipLong() throws IOException; void skipLong() throws IOException;
boolean hasInt() throws IOException;
int readInt() throws IOException;
void skipInt() throws IOException;
boolean hasDouble() throws IOException; boolean hasDouble() throws IOException;
double readDouble() throws IOException; double readDouble() throws IOException;
@@ -60,11 +54,23 @@ public interface BdfReader {
BdfList readList() throws IOException; BdfList readList() throws IOException;
void readListStart() throws IOException;
boolean hasListEnd() throws IOException;
void readListEnd() throws IOException;
void skipList() throws IOException; void skipList() throws IOException;
boolean hasDictionary() throws IOException; boolean hasDictionary() throws IOException;
BdfDictionary readDictionary() throws IOException; BdfDictionary readDictionary() throws IOException;
void readDictionaryStart() throws IOException;
boolean hasDictionaryEnd() throws IOException;
void readDictionaryEnd() throws IOException;
void skipDictionary() throws IOException; void skipDictionary() throws IOException;
} }

View File

@@ -9,8 +9,6 @@ public interface BdfReaderFactory {
BdfReader createReader(InputStream in); BdfReader createReader(InputStream in);
BdfReader createReader(InputStream in, boolean canonical);
BdfReader createReader(InputStream in, int nestedLimit, BdfReader createReader(InputStream in, int nestedLimit,
int maxBufferSize, boolean canonical); int maxBufferSize);
} }

View File

@@ -24,5 +24,13 @@ public interface BdfWriter {
void writeList(Collection<?> c) throws IOException; void writeList(Collection<?> c) throws IOException;
void writeListStart() throws IOException;
void writeListEnd() throws IOException;
void writeDictionary(Map<?, ?> m) throws IOException; void writeDictionary(Map<?, ?> m) throws IOException;
void writeDictionaryStart() throws IOException;
void writeDictionaryEnd() throws IOException;
} }

View File

@@ -1,6 +1,5 @@
package org.briarproject.bramble.api.mailbox; package org.briarproject.bramble.api.mailbox;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.lifecycle.IoExecutor;
@@ -35,16 +34,6 @@ public interface MailboxManager {
*/ */
MailboxPairingTask startPairingTask(String qrCodePayload); MailboxPairingTask startPairingTask(String qrCodePayload);
/**
* Takes a textual QR code representation in
* {@link org.briarproject.bramble.util.Base32} format and converts it
* into a qrCodePayload as expected by {@link #startPairingTask(String)}.
*
* @throws FormatException when the provided payload did not include a
* proper briar-mailbox:// link.
*/
String convertBase32Payload(String base32Payload) throws FormatException;
/** /**
* Can be used by the UI to test the mailbox connection. * Can be used by the UI to test the mailbox connection.
* *

View File

@@ -4,8 +4,6 @@ import org.briarproject.nullsafety.NotNullByDefault;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static org.briarproject.bramble.util.StringUtils.startsWithIgnoreCase;
@NotNullByDefault @NotNullByDefault
public class OsUtils { public class OsUtils {
@@ -15,15 +13,15 @@ public class OsUtils {
private static final String vendor = System.getProperty("java.vendor"); private static final String vendor = System.getProperty("java.vendor");
public static boolean isWindows() { public static boolean isWindows() {
return os != null && startsWithIgnoreCase(os, "Win"); return os != null && os.contains("Windows");
} }
public static boolean isMac() { public static boolean isMac() {
return os != null && os.equalsIgnoreCase("Mac OS X"); return os != null && os.contains("Mac OS");
} }
public static boolean isLinux() { public static boolean isLinux() {
return os != null && startsWithIgnoreCase(os, "Linux") && !isAndroid(); return os != null && os.contains("Linux") && !isAndroid();
} }
public static boolean isAndroid() { public static boolean isAndroid() {

View File

@@ -14,7 +14,6 @@ import java.util.regex.Pattern;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static java.nio.charset.CodingErrorAction.IGNORE; import static java.nio.charset.CodingErrorAction.IGNORE;
import static java.nio.charset.CodingErrorAction.REPORT;
import static java.util.regex.Pattern.CASE_INSENSITIVE; import static java.util.regex.Pattern.CASE_INSENSITIVE;
@SuppressWarnings("CharsetObjectCanBeUsed") @SuppressWarnings("CharsetObjectCanBeUsed")
@@ -53,38 +52,26 @@ public class StringUtils {
return s.getBytes(UTF_8); return s.getBytes(UTF_8);
} }
public static String fromUtf8(byte[] bytes) throws FormatException { public static String fromUtf8(byte[] bytes) {
return fromUtf8(bytes, 0, bytes.length, true); return fromUtf8(bytes, 0, bytes.length);
} }
public static String fromUtf8(byte[] bytes, int off, int len) public static String fromUtf8(byte[] bytes, int off, int len) {
throws FormatException {
return fromUtf8(bytes, off, len, true);
}
private static String fromUtf8(byte[] bytes, int off, int len,
boolean strict) throws FormatException {
CharsetDecoder decoder = UTF_8.newDecoder(); CharsetDecoder decoder = UTF_8.newDecoder();
decoder.onMalformedInput(strict ? REPORT : IGNORE); decoder.onMalformedInput(IGNORE);
decoder.onUnmappableCharacter(strict ? REPORT : IGNORE); decoder.onUnmappableCharacter(IGNORE);
ByteBuffer buffer = ByteBuffer.wrap(bytes, off, len); ByteBuffer buffer = ByteBuffer.wrap(bytes, off, len);
try { try {
return decoder.decode(buffer).toString(); return decoder.decode(buffer).toString();
} catch (CharacterCodingException e) { } catch (CharacterCodingException e) {
throw new FormatException(); throw new AssertionError(e);
} }
} }
public static String truncateUtf8(String s, int maxUtf8Length) { public static String truncateUtf8(String s, int maxUtf8Length) {
byte[] utf8 = toUtf8(s); byte[] utf8 = toUtf8(s);
if (utf8.length <= maxUtf8Length) return s; if (utf8.length <= maxUtf8Length) return s;
// Don't be strict when converting back, so that if we truncate a return fromUtf8(utf8, 0, maxUtf8Length);
// multi-byte character the whole character gets dropped
try {
return fromUtf8(utf8, 0, maxUtf8Length, false);
} catch (FormatException e) {
throw new AssertionError(e);
}
} }
/** /**
@@ -176,9 +163,4 @@ public class StringUtils {
} }
return new String(c); return new String(c);
} }
// see https://stackoverflow.com/a/38947571
static boolean startsWithIgnoreCase(String s, String prefix) {
return s.regionMatches(true, 0, prefix, 0, prefix.length());
}
} }

View File

@@ -1,7 +1,6 @@
package org.briarproject.bramble.api.data; package org.briarproject.bramble.api.data;
import org.briarproject.bramble.api.Bytes; import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.BrambleTestCase;
import org.junit.Test; import org.junit.Test;
@@ -9,12 +8,9 @@ import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
import static java.lang.Boolean.TRUE;
import static java.util.Collections.singletonMap;
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE; import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class BdfDictionaryTest extends BrambleTestCase { public class BdfDictionaryTest extends BrambleTestCase {
@@ -23,20 +19,20 @@ public class BdfDictionaryTest extends BrambleTestCase {
public void testConstructors() { public void testConstructors() {
assertEquals(Collections.<String, Object>emptyMap(), assertEquals(Collections.<String, Object>emptyMap(),
new BdfDictionary()); new BdfDictionary());
assertEquals(singletonMap("foo", NULL_VALUE), assertEquals(Collections.singletonMap("foo", NULL_VALUE),
new BdfDictionary(singletonMap("foo", NULL_VALUE))); new BdfDictionary(Collections.singletonMap("foo", NULL_VALUE)));
} }
@Test @Test
public void testFactoryMethod() { public void testFactoryMethod() {
assertEquals(Collections.<String, Object>emptyMap(), assertEquals(Collections.<String, Object>emptyMap(),
BdfDictionary.of()); BdfDictionary.of());
assertEquals(singletonMap("foo", NULL_VALUE), assertEquals(Collections.singletonMap("foo", NULL_VALUE),
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE))); BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)));
} }
@Test @Test
public void testLongPromotion() throws Exception { public void testIntegerPromotion() throws Exception {
BdfDictionary d = new BdfDictionary(); BdfDictionary d = new BdfDictionary();
d.put("foo", (byte) 1); d.put("foo", (byte) 1);
d.put("bar", (short) 2); d.put("bar", (short) 2);
@@ -48,33 +44,6 @@ public class BdfDictionaryTest extends BrambleTestCase {
assertEquals(Long.valueOf(4), d.getLong("bam")); assertEquals(Long.valueOf(4), d.getLong("bam"));
} }
@Test
public void testIntPromotionAndDemotion() throws Exception {
BdfDictionary d = new BdfDictionary();
d.put("foo", (byte) 1);
d.put("bar", (short) 2);
d.put("baz", 3);
d.put("bam", 4L);
assertEquals(Integer.valueOf(1), d.getInt("foo"));
assertEquals(Integer.valueOf(2), d.getInt("bar"));
assertEquals(Integer.valueOf(3), d.getInt("baz"));
assertEquals(Integer.valueOf(4), d.getInt("bam"));
}
@Test(expected = FormatException.class)
public void testIntUnderflow() throws Exception {
BdfDictionary d =
BdfDictionary.of(new BdfEntry("foo", Integer.MIN_VALUE - 1L));
d.getInt("foo");
}
@Test(expected = FormatException.class)
public void testIntOverflow() throws Exception {
BdfDictionary d =
BdfDictionary.of(new BdfEntry("foo", Integer.MAX_VALUE + 1L));
d.getInt("foo");
}
@Test @Test
public void testFloatPromotion() throws Exception { public void testFloatPromotion() throws Exception {
BdfDictionary d = new BdfDictionary(); BdfDictionary d = new BdfDictionary();
@@ -98,7 +67,7 @@ public class BdfDictionaryTest extends BrambleTestCase {
} }
@Test @Test
public void testKeySetIteratorIsOrderedByKeys() { public void testKeySetIteratorIsOrderedByKeys() throws Exception {
BdfDictionary d = new BdfDictionary(); BdfDictionary d = new BdfDictionary();
d.put("a", 1); d.put("a", 1);
d.put("d", 4); d.put("d", 4);
@@ -117,7 +86,7 @@ public class BdfDictionaryTest extends BrambleTestCase {
} }
@Test @Test
public void testValuesIteratorIsOrderedByKeys() { public void testValuesIteratorIsOrderedByKeys() throws Exception {
BdfDictionary d = new BdfDictionary(); BdfDictionary d = new BdfDictionary();
d.put("a", 1); d.put("a", 1);
d.put("d", 4); d.put("d", 4);
@@ -136,7 +105,7 @@ public class BdfDictionaryTest extends BrambleTestCase {
} }
@Test @Test
public void testEntrySetIteratorIsOrderedByKeys() { public void testEntrySetIteratorIsOrderedByKeys() throws Exception {
BdfDictionary d = new BdfDictionary(); BdfDictionary d = new BdfDictionary();
d.put("a", 1); d.put("a", 1);
d.put("d", 4); d.put("d", 4);
@@ -161,284 +130,4 @@ public class BdfDictionaryTest extends BrambleTestCase {
assertEquals("d", e.getKey()); assertEquals("d", e.getKey());
assertEquals(4, e.getValue()); assertEquals(4, e.getValue());
} }
@Test(expected = FormatException.class)
public void testMissingValueForBooleanThrowsFormatException()
throws Exception {
new BdfDictionary().getBoolean("foo");
}
@Test(expected = FormatException.class)
public void testMissingValueForLongThrowsFormatException()
throws Exception {
new BdfDictionary().getLong("foo");
}
@Test(expected = FormatException.class)
public void testMissingValueForIntThrowsFormatException() throws Exception {
new BdfDictionary().getInt("foo");
}
@Test(expected = FormatException.class)
public void testMissingValueForDoubleThrowsFormatException()
throws Exception {
new BdfDictionary().getDouble("foo");
}
@Test(expected = FormatException.class)
public void testMissingValueForStringThrowsFormatException()
throws Exception {
new BdfDictionary().getString("foo");
}
@Test(expected = FormatException.class)
public void testMissingValueForRawThrowsFormatException() throws Exception {
new BdfDictionary().getRaw("foo");
}
@Test(expected = FormatException.class)
public void testMissingValueForListThrowsFormatException()
throws Exception {
new BdfDictionary().getList("foo");
}
@Test(expected = FormatException.class)
public void testMissingValueForDictionaryThrowsFormatException()
throws Exception {
new BdfDictionary().getDictionary("foo");
}
@Test(expected = FormatException.class)
public void testNullValueForBooleanThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getBoolean("foo");
}
@Test(expected = FormatException.class)
public void testNullValueForLongThrowsFormatException() throws Exception {
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getLong("foo");
}
@Test(expected = FormatException.class)
public void testNullValueForIntThrowsFormatException() throws Exception {
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getInt("foo");
}
@Test(expected = FormatException.class)
public void testNullValueForDoubleThrowsFormatException() throws Exception {
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getDouble("foo");
}
@Test(expected = FormatException.class)
public void testNullValueForStringThrowsFormatException() throws Exception {
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getString("foo");
}
@Test(expected = FormatException.class)
public void testNullValueForRawThrowsFormatException() throws Exception {
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getRaw("foo");
}
@Test(expected = FormatException.class)
public void testNullValueForListThrowsFormatException() throws Exception {
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getList("foo");
}
@Test(expected = FormatException.class)
public void testNullValueForDictionaryThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getDictionary("foo");
}
@Test
public void testOptionalMethodsReturnNullForMissingValue()
throws Exception {
testOptionalMethodsReturnNull(new BdfDictionary());
}
@Test
public void testOptionalMethodsReturnNullForNullValue() throws Exception {
BdfDictionary d = BdfDictionary.of(new BdfEntry("foo", NULL_VALUE));
testOptionalMethodsReturnNull(d);
}
private void testOptionalMethodsReturnNull(BdfDictionary d)
throws Exception {
assertNull(d.getOptionalBoolean("foo"));
assertNull(d.getOptionalLong("foo"));
assertNull(d.getOptionalInt("foo"));
assertNull(d.getOptionalDouble("foo"));
assertNull(d.getOptionalString("foo"));
assertNull(d.getOptionalRaw("foo"));
assertNull(d.getOptionalList("foo"));
assertNull(d.getOptionalDictionary("foo"));
}
@Test
public void testDefaultMethodsReturnDefaultForMissingValue()
throws Exception {
testDefaultMethodsReturnDefault(new BdfDictionary());
}
@Test
public void testDefaultMethodsReturnDefaultForNullValue() throws Exception {
BdfDictionary d = BdfDictionary.of(new BdfEntry("foo", NULL_VALUE));
testDefaultMethodsReturnDefault(d);
}
private void testDefaultMethodsReturnDefault(BdfDictionary d)
throws Exception {
assertEquals(TRUE, d.getBoolean("foo", TRUE));
assertEquals(Long.valueOf(123L), d.getLong("foo", 123L));
assertEquals(Integer.valueOf(123), d.getInt("foo", 123));
assertEquals(Double.valueOf(123D), d.getDouble("foo", 123D));
assertEquals("123", d.getString("foo", "123"));
byte[] defaultRaw = {1, 2, 3};
assertArrayEquals(defaultRaw, d.getRaw("foo", defaultRaw));
BdfList defaultList = BdfList.of(1, 2, 3);
assertEquals(defaultList, d.getList("foo", defaultList));
BdfDictionary defaultDict = BdfDictionary.of(new BdfEntry("123", 123));
assertEquals(defaultDict, d.getDictionary("foo", defaultDict));
}
@Test(expected = FormatException.class)
public void testWrongTypeForBooleanThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getBoolean("foo");
}
@Test(expected = FormatException.class)
public void testWrongTypeForOptionalBooleanThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalBoolean("foo");
}
@Test(expected = FormatException.class)
public void testWrongTypeForDefaultBooleanThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getBoolean("foo", true);
}
@Test(expected = FormatException.class)
public void testWrongTypeForLongThrowsFormatException() throws Exception {
BdfDictionary.of(new BdfEntry("foo", 1.23)).getLong("foo");
}
@Test(expected = FormatException.class)
public void testWrongTypeForOptionalLongThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 1.23)).getOptionalLong("foo");
}
@Test(expected = FormatException.class)
public void testWrongTypeForDefaultLongThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 1.23)).getLong("foo", 1L);
}
@Test(expected = FormatException.class)
public void testWrongTypeForIntThrowsFormatException() throws Exception {
BdfDictionary.of(new BdfEntry("foo", 1.23)).getInt("foo");
}
@Test(expected = FormatException.class)
public void testWrongTypeForOptionalIntThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 1.23)).getOptionalInt("foo");
}
@Test(expected = FormatException.class)
public void testWrongTypeForDefaultIntThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 1.23)).getInt("foo", 1);
}
@Test(expected = FormatException.class)
public void testWrongTypeForDoubleThrowsFormatException() throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getDouble("foo");
}
@Test(expected = FormatException.class)
public void testWrongTypeForOptionalDoubleThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalDouble("foo");
}
@Test(expected = FormatException.class)
public void testWrongTypeForDefaultDoubleThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getDouble("foo", 1D);
}
@Test(expected = FormatException.class)
public void testWrongTypeForStringThrowsFormatException() throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getString("foo");
}
@Test(expected = FormatException.class)
public void testWrongTypeForOptionalStringThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalString("foo");
}
@Test(expected = FormatException.class)
public void testWrongTypeForDefaultStringThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getString("foo", "");
}
@Test(expected = FormatException.class)
public void testWrongTypeForRawThrowsFormatException() throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getRaw("foo");
}
@Test(expected = FormatException.class)
public void testWrongTypeForOptionalRawThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalRaw("foo");
}
@Test(expected = FormatException.class)
public void testWrongTypeForDefaultRawThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getRaw("foo", new byte[0]);
}
@Test(expected = FormatException.class)
public void testWrongTypeForListThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getList("foo");
}
@Test(expected = FormatException.class)
public void testWrongTypeForOptionalListThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalList("foo");
}
@Test(expected = FormatException.class)
public void testWrongTypeForDefaultListThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getList("foo",
new BdfList());
}
@Test(expected = FormatException.class)
public void testWrongTypeForDictionaryThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getDictionary("foo");
}
@Test(expected = FormatException.class)
public void testWrongTypeForOptionalDictionaryThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalDictionary("foo");
}
@Test(expected = FormatException.class)
public void testWrongTypeForDefaultDictionaryThrowsFormatException()
throws Exception {
BdfDictionary.of(new BdfEntry("foo", 123)).getDictionary("foo",
new BdfDictionary());
}
} }

View File

@@ -5,31 +5,31 @@ import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.BrambleTestCase;
import org.junit.Test; import org.junit.Test;
import static java.lang.Boolean.TRUE; import java.util.Arrays;
import static java.util.Arrays.asList; import java.util.Collections;
import static java.util.Collections.emptyList;
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE; import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
public class BdfListTest extends BrambleTestCase { public class BdfListTest extends BrambleTestCase {
@Test @Test
public void testConstructors() { public void testConstructors() {
assertEquals(emptyList(), new BdfList()); assertEquals(Collections.emptyList(), new BdfList());
assertEquals(asList(1, 2, NULL_VALUE), assertEquals(Arrays.asList(1, 2, NULL_VALUE),
new BdfList(asList(1, 2, NULL_VALUE))); new BdfList(Arrays.asList(1, 2, NULL_VALUE)));
} }
@Test @Test
public void testFactoryMethod() { public void testFactoryMethod() {
assertEquals(emptyList(), BdfList.of()); assertEquals(Collections.emptyList(), BdfList.of());
assertEquals(asList(1, 2, NULL_VALUE), BdfList.of(1, 2, NULL_VALUE)); assertEquals(Arrays.asList(1, 2, NULL_VALUE),
BdfList.of(1, 2, NULL_VALUE));
} }
@Test @Test
public void testLongPromotion() throws Exception { public void testIntegerPromotion() throws Exception {
BdfList list = new BdfList(); BdfList list = new BdfList();
list.add((byte) 1); list.add((byte) 1);
list.add((short) 2); list.add((short) 2);
@@ -41,31 +41,6 @@ public class BdfListTest extends BrambleTestCase {
assertEquals(Long.valueOf(4), list.getLong(3)); assertEquals(Long.valueOf(4), list.getLong(3));
} }
@Test
public void testIntPromotionAndDemotion() throws Exception {
BdfList list = new BdfList();
list.add((byte) 1);
list.add((short) 2);
list.add(3);
list.add(4L);
assertEquals(Integer.valueOf(1), list.getInt(0));
assertEquals(Integer.valueOf(2), list.getInt(1));
assertEquals(Integer.valueOf(3), list.getInt(2));
assertEquals(Integer.valueOf(4), list.getInt(3));
}
@Test(expected = FormatException.class)
public void testIntUnderflow() throws Exception {
BdfList list = BdfList.of(Integer.MIN_VALUE - 1L);
list.getInt(0);
}
@Test(expected = FormatException.class)
public void testIntOverflow() throws Exception {
BdfList list = BdfList.of(Integer.MAX_VALUE + 1L);
list.getInt(0);
}
@Test @Test
public void testFloatPromotion() throws Exception { public void testFloatPromotion() throws Exception {
BdfList list = new BdfList(); BdfList list = new BdfList();
@@ -88,6 +63,61 @@ public class BdfListTest extends BrambleTestCase {
assertArrayEquals(new byte[123], second); assertArrayEquals(new byte[123], second);
} }
@Test
@SuppressWarnings("ConstantConditions")
public void testIndexOutOfBoundsReturnsDefaultValue() throws Exception {
BdfList list = BdfList.of(1, 2, 3);
boolean defaultBoolean = true;
assertEquals(defaultBoolean, list.getBoolean(-1, defaultBoolean));
assertEquals(defaultBoolean, list.getBoolean(3, defaultBoolean));
Long defaultLong = 123L;
assertEquals(defaultLong, list.getLong(-1, defaultLong));
assertEquals(defaultLong, list.getLong(3, defaultLong));
Double defaultDouble = 1.23;
assertEquals(defaultDouble, list.getDouble(-1, defaultDouble));
assertEquals(defaultDouble, list.getDouble(3, defaultDouble));
String defaultString = "123";
assertEquals(defaultString, list.getString(-1, defaultString));
assertEquals(defaultString, list.getString(3, defaultString));
byte[] defaultBytes = new byte[] {1, 2, 3};
assertArrayEquals(defaultBytes, list.getRaw(-1, defaultBytes));
assertArrayEquals(defaultBytes, list.getRaw(3, defaultBytes));
BdfList defaultList = BdfList.of(1, 2, 3);
assertEquals(defaultList, list.getList(-1, defaultList));
assertEquals(defaultList, list.getList(3, defaultList));
BdfDictionary defaultDict = BdfDictionary.of(
new BdfEntry("1", 1),
new BdfEntry("2", 2),
new BdfEntry("3", 3)
);
assertEquals(defaultDict, list.getDictionary(-1, defaultDict));
assertEquals(defaultDict, list.getDictionary(3, defaultDict));
}
@Test
@SuppressWarnings("ConstantConditions")
public void testWrongTypeReturnsDefaultValue() throws Exception {
BdfList list = BdfList.of(1, 2, 3, true);
boolean defaultBoolean = true;
assertEquals(defaultBoolean, list.getBoolean(0, defaultBoolean));
Long defaultLong = 123L;
assertEquals(defaultLong, list.getLong(3, defaultLong));
Double defaultDouble = 1.23;
assertEquals(defaultDouble, list.getDouble(0, defaultDouble));
String defaultString = "123";
assertEquals(defaultString, list.getString(0, defaultString));
byte[] defaultBytes = new byte[] {1, 2, 3};
assertArrayEquals(defaultBytes, list.getRaw(0, defaultBytes));
BdfList defaultList = BdfList.of(1, 2, 3);
assertEquals(defaultList, list.getList(0, defaultList));
BdfDictionary defaultDict = BdfDictionary.of(
new BdfEntry("1", 1),
new BdfEntry("2", 2),
new BdfEntry("3", 3)
);
assertEquals(defaultDict, list.getDictionary(0, defaultDict));
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testNegativeIndexForBooleanThrowsFormatException() public void testNegativeIndexForBooleanThrowsFormatException()
throws Exception { throws Exception {
@@ -100,12 +130,6 @@ public class BdfListTest extends BrambleTestCase {
new BdfList().getOptionalBoolean(-1); new BdfList().getOptionalBoolean(-1);
} }
@Test(expected = FormatException.class)
public void testNegativeIndexForDefaultBooleanThrowsFormatException()
throws Exception {
new BdfList().getBoolean(-1, true);
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testNegativeIndexForLongThrowsFormatException() public void testNegativeIndexForLongThrowsFormatException()
throws Exception { throws Exception {
@@ -118,30 +142,6 @@ public class BdfListTest extends BrambleTestCase {
new BdfList().getOptionalLong(-1); new BdfList().getOptionalLong(-1);
} }
@Test(expected = FormatException.class)
public void testNegativeIndexForDefaultLongThrowsFormatException()
throws Exception {
new BdfList().getLong(-1, 1L);
}
@Test(expected = FormatException.class)
public void testNegativeIndexForIntThrowsFormatException()
throws Exception {
new BdfList().getInt(-1);
}
@Test(expected = FormatException.class)
public void testNegativeIndexForOptionalIntThrowsFormatException()
throws Exception {
new BdfList().getOptionalInt(-1);
}
@Test(expected = FormatException.class)
public void testNegativeIndexForDefaultIntThrowsFormatException()
throws Exception {
new BdfList().getInt(-1, 1);
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testNegativeIndexForDoubleThrowsFormatException() public void testNegativeIndexForDoubleThrowsFormatException()
throws Exception { throws Exception {
@@ -154,12 +154,6 @@ public class BdfListTest extends BrambleTestCase {
new BdfList().getOptionalDouble(-1); new BdfList().getOptionalDouble(-1);
} }
@Test(expected = FormatException.class)
public void testNegativeIndexForDefaultDoubleThrowsFormatException()
throws Exception {
new BdfList().getDouble(-1, 1D);
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testNegativeIndexForStringThrowsFormatException() public void testNegativeIndexForStringThrowsFormatException()
throws Exception { throws Exception {
@@ -172,12 +166,6 @@ public class BdfListTest extends BrambleTestCase {
new BdfList().getOptionalString(-1); new BdfList().getOptionalString(-1);
} }
@Test(expected = FormatException.class)
public void testNegativeIndexForDefaultStringThrowsFormatException()
throws Exception {
new BdfList().getString(-1, "");
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testNegativeIndexForRawThrowsFormatException() public void testNegativeIndexForRawThrowsFormatException()
throws Exception { throws Exception {
@@ -190,12 +178,6 @@ public class BdfListTest extends BrambleTestCase {
new BdfList().getOptionalRaw(-1); new BdfList().getOptionalRaw(-1);
} }
@Test(expected = FormatException.class)
public void testNegativeIndexForDefaultRawThrowsFormatException()
throws Exception {
new BdfList().getRaw(-1, new byte[0]);
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testNegativeIndexForListThrowsFormatException() public void testNegativeIndexForListThrowsFormatException()
throws Exception { throws Exception {
@@ -208,11 +190,6 @@ public class BdfListTest extends BrambleTestCase {
new BdfList().getOptionalList(-1); new BdfList().getOptionalList(-1);
} }
@Test(expected = FormatException.class)
public void testNegativeIndexForDefaultListThrowsFormatException()
throws Exception {
new BdfList().getList(-1, new BdfList());
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testNegativeIndexForDictionaryThrowsFormatException() public void testNegativeIndexForDictionaryThrowsFormatException()
@@ -226,12 +203,6 @@ public class BdfListTest extends BrambleTestCase {
new BdfList().getOptionalDictionary(-1); new BdfList().getOptionalDictionary(-1);
} }
@Test(expected = FormatException.class)
public void testNegativeIndexForDefaultDictionaryThrowsFormatException()
throws Exception {
new BdfList().getDictionary(-1, new BdfDictionary());
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testTooLargeIndexForBooleanThrowsFormatException() public void testTooLargeIndexForBooleanThrowsFormatException()
throws Exception { throws Exception {
@@ -244,12 +215,6 @@ public class BdfListTest extends BrambleTestCase {
new BdfList().getOptionalBoolean(0); new BdfList().getOptionalBoolean(0);
} }
@Test(expected = FormatException.class)
public void testTooLargeIndexForDefaultBooleanThrowsFormatException()
throws Exception {
new BdfList().getBoolean(0, true);
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testTooLargeIndexForLongThrowsFormatException() public void testTooLargeIndexForLongThrowsFormatException()
throws Exception { throws Exception {
@@ -262,30 +227,6 @@ public class BdfListTest extends BrambleTestCase {
new BdfList().getOptionalLong(0); new BdfList().getOptionalLong(0);
} }
@Test(expected = FormatException.class)
public void testTooLargeIndexForDefaultLongThrowsFormatException()
throws Exception {
new BdfList().getLong(0, 1L);
}
@Test(expected = FormatException.class)
public void testTooLargeIndexForIntThrowsFormatException()
throws Exception {
new BdfList().getInt(0);
}
@Test(expected = FormatException.class)
public void testTooLargeIndexForOptionalIntThrowsFormatException()
throws Exception {
new BdfList().getOptionalInt(0);
}
@Test(expected = FormatException.class)
public void testTooLargeIndexForDefaultIntThrowsFormatException()
throws Exception {
new BdfList().getInt(0, 1);
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testTooLargeIndexForDoubleThrowsFormatException() public void testTooLargeIndexForDoubleThrowsFormatException()
throws Exception { throws Exception {
@@ -298,12 +239,6 @@ public class BdfListTest extends BrambleTestCase {
new BdfList().getOptionalDouble(0); new BdfList().getOptionalDouble(0);
} }
@Test(expected = FormatException.class)
public void testTooLargeIndexForDefaultDoubleThrowsFormatException()
throws Exception {
new BdfList().getDouble(0, 1D);
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testTooLargeIndexForStringThrowsFormatException() public void testTooLargeIndexForStringThrowsFormatException()
throws Exception { throws Exception {
@@ -316,12 +251,6 @@ public class BdfListTest extends BrambleTestCase {
new BdfList().getOptionalString(0); new BdfList().getOptionalString(0);
} }
@Test(expected = FormatException.class)
public void testTooLargeIndexForDefaultStringThrowsFormatException()
throws Exception {
new BdfList().getString(0, "");
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testTooLargeIndexForRawThrowsFormatException() public void testTooLargeIndexForRawThrowsFormatException()
throws Exception { throws Exception {
@@ -334,12 +263,6 @@ public class BdfListTest extends BrambleTestCase {
new BdfList().getOptionalRaw(0); new BdfList().getOptionalRaw(0);
} }
@Test(expected = FormatException.class)
public void testTooLargeIndexForDefaultRawThrowsFormatException()
throws Exception {
new BdfList().getRaw(0, new byte[0]);
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testTooLargeIndexForListThrowsFormatException() public void testTooLargeIndexForListThrowsFormatException()
throws Exception { throws Exception {
@@ -352,11 +275,6 @@ public class BdfListTest extends BrambleTestCase {
new BdfList().getOptionalList(0); new BdfList().getOptionalList(0);
} }
@Test(expected = FormatException.class)
public void testTooLargeIndexForDefaultListThrowsFormatException()
throws Exception {
new BdfList().getList(0, new BdfList());
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testTooLargeIndexForDictionaryThrowsFormatException() public void testTooLargeIndexForDictionaryThrowsFormatException()
@@ -369,13 +287,6 @@ public class BdfListTest extends BrambleTestCase {
throws Exception { throws Exception {
new BdfList().getOptionalDictionary(0); new BdfList().getOptionalDictionary(0);
} }
@Test(expected = FormatException.class)
public void testTooLargeIndexForDefaultDictionaryThrowsFormatException()
throws Exception {
new BdfList().getDictionary(0, new BdfDictionary());
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testWrongTypeForBooleanThrowsFormatException() public void testWrongTypeForBooleanThrowsFormatException()
throws Exception { throws Exception {
@@ -388,12 +299,6 @@ public class BdfListTest extends BrambleTestCase {
BdfList.of(123).getOptionalBoolean(0); BdfList.of(123).getOptionalBoolean(0);
} }
@Test(expected = FormatException.class)
public void testWrongTypeForDefaultBooleanThrowsFormatException()
throws Exception {
BdfList.of(123).getBoolean(0, true);
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testWrongTypeForLongThrowsFormatException() throws Exception { public void testWrongTypeForLongThrowsFormatException() throws Exception {
BdfList.of(1.23).getLong(0); BdfList.of(1.23).getLong(0);
@@ -405,29 +310,6 @@ public class BdfListTest extends BrambleTestCase {
BdfList.of(1.23).getOptionalLong(0); BdfList.of(1.23).getOptionalLong(0);
} }
@Test(expected = FormatException.class)
public void testWrongTypeForDefaultLongThrowsFormatException()
throws Exception {
BdfList.of(1.23).getLong(0, 1L);
}
@Test(expected = FormatException.class)
public void testWrongTypeForIntThrowsFormatException() throws Exception {
BdfList.of(1.23).getInt(0);
}
@Test(expected = FormatException.class)
public void testWrongTypeForOptionalIntThrowsFormatException()
throws Exception {
BdfList.of(1.23).getOptionalInt(0);
}
@Test(expected = FormatException.class)
public void testWrongTypeForDefaultIntThrowsFormatException()
throws Exception {
BdfList.of(1.23).getInt(0, 1);
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testWrongTypeForDoubleThrowsFormatException() throws Exception { public void testWrongTypeForDoubleThrowsFormatException() throws Exception {
BdfList.of(123).getDouble(0); BdfList.of(123).getDouble(0);
@@ -439,12 +321,6 @@ public class BdfListTest extends BrambleTestCase {
BdfList.of(123).getOptionalDouble(0); BdfList.of(123).getOptionalDouble(0);
} }
@Test(expected = FormatException.class)
public void testWrongTypeForDefaultDoubleThrowsFormatException()
throws Exception {
BdfList.of(123).getDouble(0, 1D);
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testWrongTypeForStringThrowsFormatException() throws Exception { public void testWrongTypeForStringThrowsFormatException() throws Exception {
BdfList.of(123).getString(0); BdfList.of(123).getString(0);
@@ -456,12 +332,6 @@ public class BdfListTest extends BrambleTestCase {
BdfList.of(123).getOptionalString(0); BdfList.of(123).getOptionalString(0);
} }
@Test(expected = FormatException.class)
public void testWrongTypeForDefaultStringThrowsFormatException()
throws Exception {
BdfList.of(123).getString(0, "");
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testWrongTypeForRawThrowsFormatException() throws Exception { public void testWrongTypeForRawThrowsFormatException() throws Exception {
BdfList.of(123).getRaw(0); BdfList.of(123).getRaw(0);
@@ -473,12 +343,6 @@ public class BdfListTest extends BrambleTestCase {
BdfList.of(123).getOptionalRaw(0); BdfList.of(123).getOptionalRaw(0);
} }
@Test(expected = FormatException.class)
public void testWrongTypeForDefaultRawThrowsFormatException()
throws Exception {
BdfList.of(123).getRaw(0, new byte[0]);
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testWrongTypeForListThrowsFormatException() throws Exception { public void testWrongTypeForListThrowsFormatException() throws Exception {
BdfList.of(123).getList(0); BdfList.of(123).getList(0);
@@ -490,11 +354,6 @@ public class BdfListTest extends BrambleTestCase {
BdfList.of(123).getOptionalList(0); BdfList.of(123).getOptionalList(0);
} }
@Test(expected = FormatException.class)
public void testWrongTypeForDefaultListThrowsFormatException()
throws Exception {
BdfList.of(123).getList(0, new BdfList());
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testWrongTypeForDictionaryThrowsFormatException() public void testWrongTypeForDictionaryThrowsFormatException()
@@ -507,81 +366,4 @@ public class BdfListTest extends BrambleTestCase {
throws Exception { throws Exception {
BdfList.of(123).getOptionalDictionary(0); BdfList.of(123).getOptionalDictionary(0);
} }
@Test(expected = FormatException.class)
public void testWrongTypeForDefaultDictionaryThrowsFormatException()
throws Exception {
BdfList.of(123).getDictionary(0, new BdfDictionary());
}
@Test(expected = FormatException.class)
public void testNullValueForBooleanThrowsFormatException()
throws Exception {
BdfList.of(NULL_VALUE).getBoolean(0);
}
@Test(expected = FormatException.class)
public void testNullValueForLongThrowsFormatException() throws Exception {
BdfList.of(NULL_VALUE).getLong(0);
}
@Test(expected = FormatException.class)
public void testNullValueForIntThrowsFormatException() throws Exception {
BdfList.of(NULL_VALUE).getInt(0);
}
@Test(expected = FormatException.class)
public void testNullValueForDoubleThrowsFormatException() throws Exception {
BdfList.of(NULL_VALUE).getDouble(0);
}
@Test(expected = FormatException.class)
public void testNullValueForStringThrowsFormatException() throws Exception {
BdfList.of(NULL_VALUE).getString(0);
}
@Test(expected = FormatException.class)
public void testNullValueForRawThrowsFormatException() throws Exception {
BdfList.of(NULL_VALUE).getRaw(0);
}
@Test(expected = FormatException.class)
public void testNullValueForListThrowsFormatException() throws Exception {
BdfList.of(NULL_VALUE).getList(0);
}
@Test(expected = FormatException.class)
public void testNullValueForDictionaryThrowsFormatException()
throws Exception {
BdfList.of(NULL_VALUE).getDictionary(0);
}
@Test
public void testOptionalMethodsReturnNullForNullValue() throws Exception {
BdfList list = BdfList.of(NULL_VALUE);
assertNull(list.getOptionalBoolean(0));
assertNull(list.getOptionalLong(0));
assertNull(list.getOptionalInt(0));
assertNull(list.getOptionalDouble(0));
assertNull(list.getOptionalString(0));
assertNull(list.getOptionalRaw(0));
assertNull(list.getOptionalList(0));
assertNull(list.getOptionalDictionary(0));
}
@Test
public void testDefaultMethodsReturnDefaultForNullValue() throws Exception {
BdfList list = BdfList.of(NULL_VALUE);
assertEquals(TRUE, list.getBoolean(0, TRUE));
assertEquals(Long.valueOf(123L), list.getLong(0, 123L));
assertEquals(Integer.valueOf(123), list.getInt(0, 123));
assertEquals(Double.valueOf(123D), list.getDouble(0, 123D));
assertEquals("123", list.getString(0, "123"));
byte[] defaultRaw = {1, 2, 3};
assertArrayEquals(defaultRaw, list.getRaw(0, defaultRaw));
BdfList defaultList = BdfList.of(1, 2, 3);
assertEquals(defaultList, list.getList(0, defaultList));
BdfDictionary defaultDict = BdfDictionary.of(new BdfEntry("123", 123));
assertEquals(defaultDict, list.getDictionary(0, defaultDict));
}
} }

View File

@@ -155,13 +155,7 @@ class ClientHelperImpl implements ClientHelper {
@Override @Override
public BdfList getMessageAsList(Transaction txn, MessageId m) public BdfList getMessageAsList(Transaction txn, MessageId m)
throws DbException, FormatException { throws DbException, FormatException {
return getMessageAsList(txn, m, true); return toList(db.getMessage(txn, m).getBody());
}
@Override
public BdfList getMessageAsList(Transaction txn, MessageId m,
boolean canonical) throws DbException, FormatException {
return toList(db.getMessage(txn, m), canonical);
} }
@Override @Override
@@ -319,13 +313,8 @@ class ClientHelperImpl implements ClientHelper {
@Override @Override
public BdfList toList(byte[] b, int off, int len) throws FormatException { public BdfList toList(byte[] b, int off, int len) throws FormatException {
return toList(b, off, len, true);
}
private BdfList toList(byte[] b, int off, int len, boolean canonical)
throws FormatException {
ByteArrayInputStream in = new ByteArrayInputStream(b, off, len); ByteArrayInputStream in = new ByteArrayInputStream(b, off, len);
BdfReader reader = bdfReaderFactory.createReader(in, canonical); BdfReader reader = bdfReaderFactory.createReader(in);
try { try {
BdfList list = reader.readList(); BdfList list = reader.readList();
if (!reader.eof()) throw new FormatException(); if (!reader.eof()) throw new FormatException();
@@ -339,7 +328,7 @@ class ClientHelperImpl implements ClientHelper {
@Override @Override
public BdfList toList(byte[] b) throws FormatException { public BdfList toList(byte[] b) throws FormatException {
return toList(b, 0, b.length, true); return toList(b, 0, b.length);
} }
@Override @Override
@@ -347,12 +336,6 @@ class ClientHelperImpl implements ClientHelper {
return toList(m.getBody()); return toList(m.getBody());
} }
@Override
public BdfList toList(Message m, boolean canonical) throws FormatException {
byte[] b = m.getBody();
return toList(b, 0, b.length, canonical);
}
@Override @Override
public BdfList toList(Author a) { public BdfList toList(Author a) {
return BdfList.of(a.getFormatVersion(), a.getName(), a.getPublicKey()); return BdfList.of(a.getFormatVersion(), a.getName(), a.getPublicKey());
@@ -378,7 +361,7 @@ class ClientHelperImpl implements ClientHelper {
public Author parseAndValidateAuthor(BdfList author) public Author parseAndValidateAuthor(BdfList author)
throws FormatException { throws FormatException {
checkSize(author, 3); checkSize(author, 3);
int formatVersion = author.getInt(0); int formatVersion = author.getLong(0).intValue();
if (formatVersion != FORMAT_VERSION) throw new FormatException(); if (formatVersion != FORMAT_VERSION) throw new FormatException();
String name = author.getString(1); String name = author.getString(1);
checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH); checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH);
@@ -489,7 +472,8 @@ class ClientHelperImpl implements ClientHelper {
if (element.size() != 2) { if (element.size() != 2) {
throw new FormatException(); throw new FormatException();
} }
list.add(new MailboxVersion(element.getInt(0), element.getInt(1))); list.add(new MailboxVersion(element.getLong(0).intValue(),
element.getLong(1).intValue()));
} }
// Sort the list of versions for easier comparison // Sort the list of versions for easier comparison
sort(list); sort(list);
@@ -502,7 +486,7 @@ class ClientHelperImpl implements ClientHelper {
try { try {
BdfDictionary meta = BdfDictionary meta =
getGroupMetadataAsDictionary(txn, contactGroupId); getGroupMetadataAsDictionary(txn, contactGroupId);
return new ContactId(meta.getInt(GROUP_KEY_CONTACT_ID)); return new ContactId(meta.getLong(GROUP_KEY_CONTACT_ID).intValue());
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); // Invalid group metadata throw new DbException(e); // Invalid group metadata
} }

View File

@@ -18,18 +18,12 @@ class BdfReaderFactoryImpl implements BdfReaderFactory {
@Override @Override
public BdfReader createReader(InputStream in) { public BdfReader createReader(InputStream in) {
return new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT, return new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT,
DEFAULT_MAX_BUFFER_SIZE, true); DEFAULT_MAX_BUFFER_SIZE);
}
@Override
public BdfReader createReader(InputStream in, boolean canonical) {
return new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT,
DEFAULT_MAX_BUFFER_SIZE, canonical);
} }
@Override @Override
public BdfReader createReader(InputStream in, int nestedLimit, public BdfReader createReader(InputStream in, int nestedLimit,
int maxBufferSize, boolean canonical) { int maxBufferSize) {
return new BdfReaderImpl(in, nestedLimit, maxBufferSize, canonical); return new BdfReaderImpl(in, nestedLimit, maxBufferSize);
} }
} }

View File

@@ -33,24 +33,21 @@ import static org.briarproject.bramble.util.StringUtils.fromUtf8;
@NotThreadSafe @NotThreadSafe
@NotNullByDefault @NotNullByDefault
final class BdfReaderImpl implements BdfReader { class BdfReaderImpl implements BdfReader {
private static final byte[] EMPTY_BUFFER = new byte[0]; private static final byte[] EMPTY_BUFFER = new byte[0];
private final InputStream in; private final InputStream in;
private final int nestedLimit, maxBufferSize; private final int nestedLimit, maxBufferSize;
private final boolean canonical;
private boolean hasLookahead = false, eof = false; private boolean hasLookahead = false, eof = false;
private byte next; private byte next;
private byte[] buf = new byte[8]; private byte[] buf = new byte[8];
BdfReaderImpl(InputStream in, int nestedLimit, int maxBufferSize, BdfReaderImpl(InputStream in, int nestedLimit, int maxBufferSize) {
boolean canonical) {
this.in = in; this.in = in;
this.nestedLimit = nestedLimit; this.nestedLimit = nestedLimit;
this.maxBufferSize = maxBufferSize; this.maxBufferSize = maxBufferSize;
this.canonical = canonical;
} }
private void readLookahead() throws IOException { private void readLookahead() throws IOException {
@@ -191,22 +188,13 @@ final class BdfReaderImpl implements BdfReader {
private short readInt16() throws IOException { private short readInt16() throws IOException {
readIntoBuffer(2); readIntoBuffer(2);
short value = (short) (((buf[0] & 0xFF) << 8) + (buf[1] & 0xFF)); return (short) (((buf[0] & 0xFF) << 8) + (buf[1] & 0xFF));
if (canonical && value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
// Value could have been encoded as an INT_8
throw new FormatException();
}
return value;
} }
private int readInt32() throws IOException { private int readInt32() throws IOException {
readIntoBuffer(4); readIntoBuffer(4);
int value = 0; int value = 0;
for (int i = 0; i < 4; i++) value |= (buf[i] & 0xFF) << (24 - i * 8); for (int i = 0; i < 4; i++) value |= (buf[i] & 0xFF) << (24 - i * 8);
if (canonical && value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
// Value could have been encoded as an INT_16
throw new FormatException();
}
return value; return value;
} }
@@ -214,11 +202,6 @@ final class BdfReaderImpl implements BdfReader {
readIntoBuffer(8); readIntoBuffer(8);
long value = 0; long value = 0;
for (int i = 0; i < 8; i++) value |= (buf[i] & 0xFFL) << (56 - i * 8); for (int i = 0; i < 8; i++) value |= (buf[i] & 0xFFL) << (56 - i * 8);
if (canonical && value >= Integer.MIN_VALUE &&
value <= Integer.MAX_VALUE) {
// Value could have been encoded as an INT_32
throw new FormatException();
}
return value; return value;
} }
@@ -232,31 +215,6 @@ final class BdfReaderImpl implements BdfReader {
hasLookahead = false; hasLookahead = false;
} }
@Override
public boolean hasInt() throws IOException {
if (!hasLookahead) readLookahead();
if (eof) return false;
return next == INT_8 || next == INT_16 || next == INT_32;
}
@Override
public int readInt() throws IOException {
if (!hasInt()) throw new FormatException();
hasLookahead = false;
if (next == INT_8) return readInt8();
if (next == INT_16) return readInt16();
return readInt32();
}
@Override
public void skipInt() throws IOException {
if (!hasInt()) throw new FormatException();
if (next == INT_8) skip(1);
else if (next == INT_16) skip(2);
else skip(4);
hasLookahead = false;
}
@Override @Override
public boolean hasDouble() throws IOException { public boolean hasDouble() throws IOException {
if (!hasLookahead) readLookahead(); if (!hasLookahead) readLookahead();
@@ -365,19 +323,35 @@ final class BdfReaderImpl implements BdfReader {
private BdfList readList(int level) throws IOException { private BdfList readList(int level) throws IOException {
if (!hasList()) throw new FormatException(); if (!hasList()) throw new FormatException();
if (level > nestedLimit) throw new FormatException(); if (level > nestedLimit) throw new FormatException();
hasLookahead = false;
BdfList list = new BdfList(); BdfList list = new BdfList();
while (!hasEnd()) list.add(readObject(level + 1)); readListStart();
readEnd(); while (!hasListEnd()) list.add(readObject(level + 1));
readListEnd();
return list; return list;
} }
@Override
public void readListStart() throws IOException {
if (!hasList()) throw new FormatException();
hasLookahead = false;
}
@Override
public boolean hasListEnd() throws IOException {
return hasEnd();
}
private boolean hasEnd() throws IOException { private boolean hasEnd() throws IOException {
if (!hasLookahead) readLookahead(); if (!hasLookahead) readLookahead();
if (eof) return false; if (eof) return false;
return next == END; return next == END;
} }
@Override
public void readListEnd() throws IOException {
readEnd();
}
private void readEnd() throws IOException { private void readEnd() throws IOException {
if (!hasEnd()) throw new FormatException(); if (!hasEnd()) throw new FormatException();
hasLookahead = false; hasLookahead = false;
@@ -387,7 +361,7 @@ final class BdfReaderImpl implements BdfReader {
public void skipList() throws IOException { public void skipList() throws IOException {
if (!hasList()) throw new FormatException(); if (!hasList()) throw new FormatException();
hasLookahead = false; hasLookahead = false;
while (!hasEnd()) skipObject(); while (!hasListEnd()) skipObject();
hasLookahead = false; hasLookahead = false;
} }
@@ -406,27 +380,35 @@ final class BdfReaderImpl implements BdfReader {
private BdfDictionary readDictionary(int level) throws IOException { private BdfDictionary readDictionary(int level) throws IOException {
if (!hasDictionary()) throw new FormatException(); if (!hasDictionary()) throw new FormatException();
if (level > nestedLimit) throw new FormatException(); if (level > nestedLimit) throw new FormatException();
hasLookahead = false;
BdfDictionary dictionary = new BdfDictionary(); BdfDictionary dictionary = new BdfDictionary();
String prevKey = null; readDictionaryStart();
while (!hasEnd()) { while (!hasDictionaryEnd())
String key = readString(); dictionary.put(readString(), readObject(level + 1));
if (canonical && prevKey != null && key.compareTo(prevKey) <= 0) { readDictionaryEnd();
// Keys not unique and sorted
throw new FormatException();
}
dictionary.put(key, readObject(level + 1));
prevKey = key;
}
readEnd();
return dictionary; return dictionary;
} }
@Override
public void readDictionaryStart() throws IOException {
if (!hasDictionary()) throw new FormatException();
hasLookahead = false;
}
@Override
public boolean hasDictionaryEnd() throws IOException {
return hasEnd();
}
@Override
public void readDictionaryEnd() throws IOException {
readEnd();
}
@Override @Override
public void skipDictionary() throws IOException { public void skipDictionary() throws IOException {
if (!hasDictionary()) throw new FormatException(); if (!hasDictionary()) throw new FormatException();
hasLookahead = false; hasLookahead = false;
while (!hasEnd()) { while (!hasDictionaryEnd()) {
skipString(); skipString();
skipObject(); skipObject();
} }

View File

@@ -2,13 +2,11 @@ package org.briarproject.bramble.data;
import org.briarproject.bramble.api.Bytes; import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfWriter; import org.briarproject.bramble.api.data.BdfWriter;
import org.briarproject.nullsafety.NotNullByDefault; import org.briarproject.nullsafety.NotNullByDefault;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -17,7 +15,6 @@ import java.util.Map.Entry;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe; import javax.annotation.concurrent.NotThreadSafe;
import static java.util.Collections.sort;
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE; import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
import static org.briarproject.bramble.data.Types.DICTIONARY; import static org.briarproject.bramble.data.Types.DICTIONARY;
import static org.briarproject.bramble.data.Types.END; import static org.briarproject.bramble.data.Types.END;
@@ -36,11 +33,10 @@ import static org.briarproject.bramble.data.Types.STRING_16;
import static org.briarproject.bramble.data.Types.STRING_32; import static org.briarproject.bramble.data.Types.STRING_32;
import static org.briarproject.bramble.data.Types.STRING_8; import static org.briarproject.bramble.data.Types.STRING_8;
import static org.briarproject.bramble.data.Types.TRUE; import static org.briarproject.bramble.data.Types.TRUE;
import static org.briarproject.bramble.util.StringUtils.UTF_8;
@NotThreadSafe @NotThreadSafe
@NotNullByDefault @NotNullByDefault
final class BdfWriterImpl implements BdfWriter { class BdfWriterImpl implements BdfWriter {
private final OutputStream out; private final OutputStream out;
@@ -117,7 +113,7 @@ final class BdfWriterImpl implements BdfWriter {
@Override @Override
public void writeString(String s) throws IOException { public void writeString(String s) throws IOException {
byte[] b = s.getBytes(UTF_8); byte[] b = s.getBytes("UTF-8");
if (b.length <= Byte.MAX_VALUE) { if (b.length <= Byte.MAX_VALUE) {
out.write(STRING_8); out.write(STRING_8);
out.write((byte) b.length); out.write((byte) b.length);
@@ -165,33 +161,39 @@ final class BdfWriterImpl implements BdfWriter {
else if (o instanceof String) writeString((String) o); else if (o instanceof String) writeString((String) o);
else if (o instanceof byte[]) writeRaw((byte[]) o); else if (o instanceof byte[]) writeRaw((byte[]) o);
else if (o instanceof Bytes) writeRaw(((Bytes) o).getBytes()); else if (o instanceof Bytes) writeRaw(((Bytes) o).getBytes());
else if (o instanceof List) writeList((List<?>) o); else if (o instanceof List) writeList((List) o);
else if (o instanceof Map) writeDictionary((Map<?, ?>) o); else if (o instanceof Map) writeDictionary((Map) o);
else throw new FormatException(); else throw new FormatException();
} }
@Override
public void writeListStart() throws IOException {
out.write(LIST);
}
@Override
public void writeListEnd() throws IOException {
out.write(END);
}
@Override @Override
public void writeDictionary(Map<?, ?> m) throws IOException { public void writeDictionary(Map<?, ?> m) throws IOException {
out.write(DICTIONARY); out.write(DICTIONARY);
if (m instanceof BdfDictionary) { for (Entry<?, ?> e : m.entrySet()) {
// Entries are already sorted and keys are known to be strings if (!(e.getKey() instanceof String)) throw new FormatException();
for (Entry<String, Object> e : ((BdfDictionary) m).entrySet()) { writeString((String) e.getKey());
writeString(e.getKey()); writeObject(e.getValue());
writeObject(e.getValue());
}
} else {
// Check that keys are strings, write entries in canonical order
List<String> keys = new ArrayList<>(m.size());
for (Object k : m.keySet()) {
if (!(k instanceof String)) throw new FormatException();
keys.add((String) k);
}
sort(keys);
for (String key : keys) {
writeString(key);
writeObject(m.get(key));
}
} }
out.write(END); out.write(END);
} }
@Override
public void writeDictionaryStart() throws IOException {
out.write(DICTIONARY);
}
@Override
public void writeDictionaryEnd() throws IOException {
out.write(END);
}
} }

View File

@@ -1,6 +1,5 @@
package org.briarproject.bramble.keyagreement; package org.briarproject.bramble.keyagreement;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.data.BdfWriter; import org.briarproject.bramble.api.data.BdfWriter;
import org.briarproject.bramble.api.data.BdfWriterFactory; import org.briarproject.bramble.api.data.BdfWriterFactory;
import org.briarproject.bramble.api.keyagreement.Payload; import org.briarproject.bramble.api.keyagreement.Payload;
@@ -33,14 +32,13 @@ class PayloadEncoderImpl implements PayloadEncoder {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
int formatIdAndVersion = (QR_FORMAT_ID << 5) | QR_FORMAT_VERSION; int formatIdAndVersion = (QR_FORMAT_ID << 5) | QR_FORMAT_VERSION;
out.write(formatIdAndVersion); out.write(formatIdAndVersion);
BdfList payload = new BdfList();
payload.add(p.getCommitment());
for (TransportDescriptor d : p.getTransportDescriptors()) {
payload.add(d.getDescriptor());
}
BdfWriter w = bdfWriterFactory.createWriter(out); BdfWriter w = bdfWriterFactory.createWriter(out);
try { try {
w.writeList(payload); w.writeListStart(); // Payload start
w.writeRaw(p.getCommitment());
for (TransportDescriptor d : p.getTransportDescriptors())
w.writeList(d.getDescriptor());
w.writeListEnd(); // Payload end
} catch (IOException e) { } catch (IOException e) {
// Shouldn't happen with ByteArrayOutputStream // Shouldn't happen with ByteArrayOutputStream
throw new AssertionError(e); throw new AssertionError(e);

View File

@@ -73,7 +73,7 @@ class PayloadParserImpl implements PayloadParser {
List<TransportDescriptor> recognised = new ArrayList<>(); List<TransportDescriptor> recognised = new ArrayList<>();
for (int i = 1; i < payload.size(); i++) { for (int i = 1; i < payload.size(); i++) {
BdfList descriptor = payload.getList(i); BdfList descriptor = payload.getList(i);
int transportId = descriptor.getInt(0); long transportId = descriptor.getLong(0);
if (transportId == TRANSPORT_ID_BLUETOOTH) { if (transportId == TRANSPORT_ID_BLUETOOTH) {
TransportId id = BluetoothConstants.ID; TransportId id = BluetoothConstants.ID;
recognised.add(new TransportDescriptor(id, descriptor)); recognised.add(new TransportDescriptor(id, descriptor));

View File

@@ -1,6 +1,5 @@
package org.briarproject.bramble.mailbox; package org.briarproject.bramble.mailbox;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.db.TransactionManager; import org.briarproject.bramble.api.db.TransactionManager;
@@ -12,15 +11,12 @@ import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
import org.briarproject.bramble.api.mailbox.MailboxStatus; import org.briarproject.bramble.api.mailbox.MailboxStatus;
import org.briarproject.bramble.api.mailbox.MailboxVersion; import org.briarproject.bramble.api.mailbox.MailboxVersion;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.util.Base32;
import org.briarproject.nullsafety.NotNullByDefault; import org.briarproject.nullsafety.NotNullByDefault;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy; import javax.annotation.concurrent.GuardedBy;
@@ -30,7 +26,6 @@ import javax.inject.Inject;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger; import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
@@ -103,22 +98,6 @@ class MailboxManagerImpl implements MailboxManager {
return created; return created;
} }
@Override
public String convertBase32Payload(String base32Payload)
throws FormatException {
Pattern regex = Pattern.compile("(briar-mailbox://)?([a-z2-7]{104})");
Matcher matcher = regex.matcher(base32Payload);
if (!matcher.find()) throw new FormatException();
String base32 = matcher.group(2);
byte[] payloadBytes;
try {
payloadBytes = Base32.decode(base32, false);
} catch (IllegalArgumentException e) {
throw new FormatException();
}
return new String(payloadBytes, ISO_8859_1);
}
@Override @Override
public boolean checkConnection() { public boolean checkConnection() {
List<MailboxVersion> versions = null; List<MailboxVersion> versions = null;

View File

@@ -419,7 +419,7 @@ class LanTcpPlugin extends TcpPlugin {
private InetSocketAddress parseSocketAddress(BdfList descriptor) private InetSocketAddress parseSocketAddress(BdfList descriptor)
throws FormatException { throws FormatException {
byte[] address = descriptor.getRaw(1); byte[] address = descriptor.getRaw(1);
int port = descriptor.getInt(2); int port = descriptor.getLong(2).intValue();
if (port < 1 || port > MAX_16_BIT_UNSIGNED) throw new FormatException(); if (port < 1 || port > MAX_16_BIT_UNSIGNED) throw new FormatException();
try { try {
InetAddress addr = InetAddress.getByAddress(address); InetAddress addr = InetAddress.getByAddress(address);

View File

@@ -55,6 +55,7 @@ import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.zip.ZipInputStream;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy; import javax.annotation.concurrent.GuardedBy;
@@ -100,7 +101,6 @@ import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubOnion; import static org.briarproject.bramble.util.PrivacyUtils.scrubOnion;
import static org.briarproject.bramble.util.StringUtils.UTF_8; import static org.briarproject.bramble.util.StringUtils.UTF_8;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
import static org.briarproject.nullsafety.NullSafety.requireNonNull;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
@@ -208,10 +208,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
return new File(torDirectory, "tor"); return new File(torDirectory, "tor");
} }
private File getLibEventFile() {
return new File(torDirectory, "libevent-2.1.7.dylib");
}
protected File getObfs4ExecutableFile() { protected File getObfs4ExecutableFile() {
return new File(torDirectory, "obfs4proxy"); return new File(torDirectory, "obfs4proxy");
} }
@@ -352,9 +348,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
LOG.info("Installing Tor binary for " + architecture); LOG.info("Installing Tor binary for " + architecture);
File torFile = getTorExecutableFile(); File torFile = getTorExecutableFile();
File libEventFile = getLibEventFile(); extract(getTorInputStream(), torFile);
extract(getExecutableInputStream("tor"), torFile);
extract(getExecutableInputStream("libevent-2.1.7.dylib"), libEventFile);
if (!torFile.setExecutable(true, true)) throw new IOException(); if (!torFile.setExecutable(true, true)) throw new IOException();
} }
@@ -362,7 +356,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
LOG.info("Installing obfs4proxy binary for " + architecture); LOG.info("Installing obfs4proxy binary for " + architecture);
File obfs4File = getObfs4ExecutableFile(); File obfs4File = getObfs4ExecutableFile();
extract(getExecutableInputStream("obfs4proxy"), obfs4File); extract(getObfs4InputStream(), obfs4File);
if (!obfs4File.setExecutable(true, true)) throw new IOException(); if (!obfs4File.setExecutable(true, true)) throw new IOException();
} }
@@ -370,18 +364,28 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
LOG.info("Installing snowflake binary for " + architecture); LOG.info("Installing snowflake binary for " + architecture);
File snowflakeFile = getSnowflakeExecutableFile(); File snowflakeFile = getSnowflakeExecutableFile();
extract(getExecutableInputStream("snowflake"), snowflakeFile); extract(getSnowflakeInputStream(), snowflakeFile);
if (!snowflakeFile.setExecutable(true, true)) throw new IOException(); if (!snowflakeFile.setExecutable(true, true)) throw new IOException();
} }
private InputStream getExecutableInputStream(String basename) { private InputStream getTorInputStream() throws IOException {
String ext = getExecutableExtension(); return getZipInputStream("tor");
return requireNonNull(resourceProvider
.getResourceInputStream(architecture + "/" + basename, ext));
} }
protected String getExecutableExtension() { private InputStream getObfs4InputStream() throws IOException {
return ""; return getZipInputStream("obfs4proxy");
}
private InputStream getSnowflakeInputStream() throws IOException {
return getZipInputStream("snowflake");
}
private InputStream getZipInputStream(String basename) throws IOException {
InputStream in = resourceProvider
.getResourceInputStream(basename + "_" + architecture, ".zip");
ZipInputStream zin = new ZipInputStream(in);
if (zin.getNextEntry() == null) throw new IOException();
return zin;
} }
private static void append(StringBuilder strb, String name, Object value) { private static void append(StringBuilder strb, String name, Object value) {

View File

@@ -201,7 +201,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
// Retrieve and parse the latest local properties // Retrieve and parse the latest local properties
for (Entry<TransportId, LatestUpdate> e : latest.entrySet()) { for (Entry<TransportId, LatestUpdate> e : latest.entrySet()) {
BdfList message = clientHelper.getMessageAsList(txn, BdfList message = clientHelper.getMessageAsList(txn,
e.getValue().messageId, false); e.getValue().messageId);
local.put(e.getKey(), parseProperties(message)); local.put(e.getKey(), parseProperties(message));
} }
return local; return local;
@@ -222,7 +222,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
if (latest != null) { if (latest != null) {
// Retrieve and parse the latest local properties // Retrieve and parse the latest local properties
BdfList message = clientHelper.getMessageAsList(txn, BdfList message = clientHelper.getMessageAsList(txn,
latest.messageId, false); latest.messageId);
p = parseProperties(message); p = parseProperties(message);
} }
return p == null ? new TransportProperties() : p; return p == null ? new TransportProperties() : p;
@@ -252,7 +252,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
local = new TransportProperties(); local = new TransportProperties();
} else { } else {
BdfList message = clientHelper.getMessageAsList(txn, BdfList message = clientHelper.getMessageAsList(txn,
latest.messageId, false); latest.messageId);
local = parseProperties(message); local = parseProperties(message);
} }
storeLocalProperties(txn, c, t, local); storeLocalProperties(txn, c, t, local);
@@ -272,8 +272,8 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
remote = new TransportProperties(); remote = new TransportProperties();
} else { } else {
// Retrieve and parse the latest remote properties // Retrieve and parse the latest remote properties
BdfList message = clientHelper.getMessageAsList(txn, BdfList message =
latest.messageId, false); clientHelper.getMessageAsList(txn, latest.messageId);
remote = parseProperties(message); remote = parseProperties(message);
} }
// Merge in any discovered properties // Merge in any discovered properties
@@ -317,7 +317,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
changed = true; changed = true;
} else { } else {
BdfList message = clientHelper.getMessageAsList(txn, BdfList message = clientHelper.getMessageAsList(txn,
latest.messageId, false); latest.messageId);
TransportProperties old = parseProperties(message); TransportProperties old = parseProperties(message);
merged = new TransportProperties(old); merged = new TransportProperties(old);
for (Entry<String, String> e : p.entrySet()) { for (Entry<String, String> e : p.entrySet()) {

View File

@@ -27,10 +27,7 @@ class TransportPropertyValidator extends BdfMessageValidator {
TransportPropertyValidator(ClientHelper clientHelper, TransportPropertyValidator(ClientHelper clientHelper,
MetadataEncoder metadataEncoder, Clock clock) { MetadataEncoder metadataEncoder, Clock clock) {
// Accept transport properties in non-canonical form super(clientHelper, metadataEncoder, clock);
// TODO: Remove this after a reasonable migration period
// (added 2023-02-17)
super(clientHelper, metadataEncoder, clock, false);
} }
@Override @Override

View File

@@ -30,7 +30,6 @@ import static org.briarproject.bramble.api.sync.RecordTypes.OFFER;
import static org.briarproject.bramble.api.sync.RecordTypes.PRIORITY; import static org.briarproject.bramble.api.sync.RecordTypes.PRIORITY;
import static org.briarproject.bramble.api.sync.RecordTypes.REQUEST; import static org.briarproject.bramble.api.sync.RecordTypes.REQUEST;
import static org.briarproject.bramble.api.sync.RecordTypes.VERSIONS; import static org.briarproject.bramble.api.sync.RecordTypes.VERSIONS;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_SUPPORTED_VERSIONS; import static org.briarproject.bramble.api.sync.SyncConstants.MAX_SUPPORTED_VERSIONS;
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH; import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.PRIORITY_NONCE_BYTES; import static org.briarproject.bramble.api.sync.SyncConstants.PRIORITY_NONCE_BYTES;
@@ -127,8 +126,6 @@ class SyncRecordReaderImpl implements SyncRecordReader {
byte[] payload = nextRecord.getPayload(); byte[] payload = nextRecord.getPayload();
if (payload.length <= MESSAGE_HEADER_LENGTH) if (payload.length <= MESSAGE_HEADER_LENGTH)
throw new FormatException(); throw new FormatException();
if (payload.length > MAX_MESSAGE_LENGTH)
throw new FormatException();
// Validate timestamp // Validate timestamp
long timestamp = ByteUtils.readUint64(payload, UniqueId.LENGTH); long timestamp = ByteUtils.readUint64(payload, UniqueId.LENGTH);
if (timestamp < 0) throw new FormatException(); if (timestamp < 0) throw new FormatException();

View File

@@ -32,7 +32,8 @@ class SessionParserImpl implements SessionParser {
@Override @Override
public Session parseSession(BdfDictionary meta) throws FormatException { public Session parseSession(BdfDictionary meta) throws FormatException {
State state = State.fromValue(meta.getInt(SESSION_KEY_STATE)); State state =
State.fromValue(meta.getLong(SESSION_KEY_STATE).intValue());
MessageId lastLocalMessageId = null; MessageId lastLocalMessageId = null;
byte[] lastLocalMessageIdBytes = byte[] lastLocalMessageIdBytes =
@@ -55,9 +56,9 @@ class SessionParserImpl implements SessionParser {
Long localTimestamp = meta.getOptionalLong(SESSION_KEY_LOCAL_TIMESTAMP); Long localTimestamp = meta.getOptionalLong(SESSION_KEY_LOCAL_TIMESTAMP);
KeySetId keySetId = null; KeySetId keySetId = null;
Integer keySetIdInt = meta.getOptionalInt(SESSION_KEY_KEY_SET_ID); Long keySetIdLong = meta.getOptionalLong(SESSION_KEY_KEY_SET_ID);
if (keySetIdInt != null) { if (keySetIdLong != null) {
keySetId = new KeySetId(keySetIdInt); keySetId = new KeySetId(keySetIdLong.intValue());
} }
return new Session(state, lastLocalMessageId, localKeyPair, return new Session(state, lastLocalMessageId, localKeyPair,

View File

@@ -177,8 +177,8 @@ class TransportKeyAgreementManagerImpl extends BdfIncomingMessageHook
protected DeliveryAction incomingMessage(Transaction txn, Message m, protected DeliveryAction incomingMessage(Transaction txn, Message m,
BdfList body, BdfDictionary meta) BdfList body, BdfDictionary meta)
throws DbException, FormatException { throws DbException, FormatException {
MessageType type = MessageType type = MessageType.fromValue(
MessageType.fromValue(meta.getInt(MSG_KEY_MESSAGE_TYPE)); meta.getLong(MSG_KEY_MESSAGE_TYPE).intValue());
TransportId t = new TransportId(meta.getString(MSG_KEY_TRANSPORT_ID)); TransportId t = new TransportId(meta.getString(MSG_KEY_TRANSPORT_ID));
if (LOG.isLoggable(INFO)) { if (LOG.isLoggable(INFO)) {
LOG.info("Received " + type + " message for " + t); LOG.info("Received " + type + " message for " + t);

View File

@@ -42,7 +42,7 @@ class TransportKeyAgreementValidator extends BdfMessageValidator {
@Override @Override
protected BdfMessageContext validateMessage(Message m, Group g, protected BdfMessageContext validateMessage(Message m, Group g,
BdfList body) throws FormatException { BdfList body) throws FormatException {
MessageType type = MessageType.fromValue(body.getInt(0)); MessageType type = MessageType.fromValue(body.getLong(0).intValue());
if (type == KEY) return validateKeyMessage(m.getTimestamp(), body); if (type == KEY) return validateKeyMessage(m.getTimestamp(), body);
else if (type == ACTIVATE) return validateActivateMessage(body); else if (type == ACTIVATE) return validateActivateMessage(body);
else throw new AssertionError(); else throw new AssertionError();

View File

@@ -301,8 +301,8 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
BdfList cv = body.getList(i); BdfList cv = body.getList(i);
ClientId clientId = new ClientId(cv.getString(0)); ClientId clientId = new ClientId(cv.getString(0));
int majorVersion = cv.getInt(1); int majorVersion = cv.getLong(1).intValue();
int minorVersion = cv.getInt(2); int minorVersion = cv.getLong(2).intValue();
parsed.add(new ClientVersion(clientId, majorVersion, minorVersion)); parsed.add(new ClientVersion(clientId, majorVersion, minorVersion));
} }
return parsed; return parsed;
@@ -408,8 +408,8 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
throws FormatException { throws FormatException {
// Client ID, major version, minor version, active // Client ID, major version, minor version, active
ClientId clientId = new ClientId(clientState.getString(0)); ClientId clientId = new ClientId(clientState.getString(0));
int majorVersion = clientState.getInt(1); int majorVersion = clientState.getLong(1).intValue();
int minorVersion = clientState.getInt(2); int minorVersion = clientState.getLong(2).intValue();
boolean active = clientState.getBoolean(3); boolean active = clientState.getBoolean(3);
return new ClientState(clientId, majorVersion, minorVersion, active); return new ClientState(clientId, majorVersion, minorVersion, active);
} }

View File

@@ -43,9 +43,9 @@ class ClientVersioningValidator extends BdfMessageValidator {
checkSize(clientState, 4); checkSize(clientState, 4);
String clientId = clientState.getString(0); String clientId = clientState.getString(0);
checkLength(clientId, 1, MAX_CLIENT_ID_LENGTH); checkLength(clientId, 1, MAX_CLIENT_ID_LENGTH);
int majorVersion = clientState.getInt(1); int majorVersion = clientState.getLong(1).intValue();
if (majorVersion < 0) throw new FormatException(); if (majorVersion < 0) throw new FormatException();
int minorVersion = clientState.getInt(2); int minorVersion = clientState.getLong(2).intValue();
if (minorVersion < 0) throw new FormatException(); if (minorVersion < 0) throw new FormatException();
clientState.getBoolean(3); clientState.getBoolean(3);
} }

View File

@@ -10,21 +10,22 @@ d Bridge obfs4 146.57.248.225:22 10A6CD36A537FCE513A322361547444B393989F0 cert=K
d Bridge obfs4 45.145.95.6:27015 C5B7CD6946FF10C5B3E89691A7D3F2C122D2117C cert=TD7PbUO0/0k6xYHMPW3vJxICfkMZNdkRrb63Zhl5j9dW3iRGiCx0A7mPhe5T2EDzQ35+Zw iat-mode=0 d Bridge obfs4 45.145.95.6:27015 C5B7CD6946FF10C5B3E89691A7D3F2C122D2117C cert=TD7PbUO0/0k6xYHMPW3vJxICfkMZNdkRrb63Zhl5j9dW3iRGiCx0A7mPhe5T2EDzQ35+Zw iat-mode=0
d Bridge obfs4 51.222.13.177:80 5EDAC3B810E12B01F6FD8050D2FD3E277B289A08 cert=2uplIpLQ0q9+0qMFrK5pkaYRDOe460LL9WHBvatgkuRr/SL31wBOEupaMMJ6koRE6Ld0ew iat-mode=0 d Bridge obfs4 51.222.13.177:80 5EDAC3B810E12B01F6FD8050D2FD3E277B289A08 cert=2uplIpLQ0q9+0qMFrK5pkaYRDOe460LL9WHBvatgkuRr/SL31wBOEupaMMJ6koRE6Ld0ew iat-mode=0
n Bridge obfs4 185.181.11.86:443 A961609729E7FDF520B4E81F1F1B8FA1045285C3 cert=e5faG9Zk4Ni+e7z2YgGfevyKPQlMvkVGi4ublSsHYjaBovKeNXpOhbeFxzbZZoAzxAoGUQ iat-mode=0 n Bridge obfs4 185.181.11.86:443 A961609729E7FDF520B4E81F1F1B8FA1045285C3 cert=e5faG9Zk4Ni+e7z2YgGfevyKPQlMvkVGi4ublSsHYjaBovKeNXpOhbeFxzbZZoAzxAoGUQ iat-mode=0
n Bridge obfs4 93.95.226.151:41185 460B0CFFC0CF1D965F3DE064E08BA1915E7C916A cert=inluPzp5Jp5OzZar1eQb4dcQ/YlAj/v0kHAUCoCr3rmLt03+pVuVTjoH4mRy4+acXpn+Gw iat-mode=0
n Bridge obfs4 120.29.217.52:5223 40FE3DB9800272F9CDC76422F8ED7883280EE96D cert=/71PS4l8c/XJ4DIItlH9xMqNvPFg2RUTrHvPlQWh48u5et8h/yyyjCcYphUadDsfBWpaGQ iat-mode=0 n Bridge obfs4 120.29.217.52:5223 40FE3DB9800272F9CDC76422F8ED7883280EE96D cert=/71PS4l8c/XJ4DIItlH9xMqNvPFg2RUTrHvPlQWh48u5et8h/yyyjCcYphUadDsfBWpaGQ iat-mode=0
n Bridge obfs4 185.177.207.138:8443 53716FE26F23C8C6A71A2BC5D9D8DC64747278C7 cert=6jcYVilMEzxdsWghSrQFpYYJlkkir/GPIXw/EnddUK3S8ToVpMG8u1SwMOEdEs735RrMHw iat-mode=0 n Bridge obfs4 185.177.207.138:8443 53716FE26F23C8C6A71A2BC5D9D8DC64747278C7 cert=6jcYVilMEzxdsWghSrQFpYYJlkkir/GPIXw/EnddUK3S8ToVpMG8u1SwMOEdEs735RrMHw iat-mode=0
n Bridge obfs4 104.168.68.90:443 ED55B3C321E44EA7E50EF568C8A63CF75E89A58C cert=fgonxDvltTp8nmcOE9sUG94eOAALxETVVXAwnTZJLPpf7rjPuTp+abKl4VyFkxfcLRr5KQ iat-mode=0
n Bridge obfs4 45.142.181.131:42069 6EBCF6B02DA2B982F4080A7119D737366AFB74FA cert=9HyWH/BCwWzNirZdTQtluCgJk+gFhpOqydIuyQ1iDvpnqsAynKF+zcPE/INZFefm86UlBg iat-mode=0 n Bridge obfs4 45.142.181.131:42069 6EBCF6B02DA2B982F4080A7119D737366AFB74FA cert=9HyWH/BCwWzNirZdTQtluCgJk+gFhpOqydIuyQ1iDvpnqsAynKF+zcPE/INZFefm86UlBg iat-mode=0
n Bridge obfs4 85.214.28.204:47111 78A36E46BB082A471848239D3F4390A8F8C6084D cert=96sr3eaUFBDu4wFVAQIfNFElh0UNuutJ/3/Fh2Vu2PHfacQ8bwfY02bwG351U8BZpLnfUQ iat-mode=0
n Bridge obfs4 152.67.77.101:4096 B82DB9CDDF887AB8A859420E07DF298E30AF8A6E cert=21OWn3yFo+hulmQNAOtF5uwwOqWtdT5PrLhk8BG9DpOd0/k5DEkQEYPyDdXbS9nZ0E5BJA iat-mode=0 n Bridge obfs4 152.67.77.101:4096 B82DB9CDDF887AB8A859420E07DF298E30AF8A6E cert=21OWn3yFo+hulmQNAOtF5uwwOqWtdT5PrLhk8BG9DpOd0/k5DEkQEYPyDdXbS9nZ0E5BJA iat-mode=0
n Bridge obfs4 185.103.252.72:443 75F15E9339FF572F88F5588D429FEA379744BC53 cert=nOZ/SaRE3L1dChvjfe0Ks/wM/F8iFhwd3g2G5zgtcLB8x+wiZRWCwjRrbbiQyb3Gh2mxRQ iat-mode=0
n Bridge obfs4 76.255.201.112:8888 96CF36C2ECCFB7376AB6BE905BECD2C2AE8AEFCD cert=+q0pjaiM0JMqHL/BKqCRD+pjflaw/S406eUDF7CnFgamvQW3l2HVLJhQ6uX9P8zff0PLGg iat-mode=0
n Bridge obfs4 94.142.246.132:8088 135C158527AA9FE9A2F26EC515EB6999D813D347 cert=wTUz0/5FhAZRkitil5MprGbSF3JzjxjxI1kAmxAdSeDy98NgcLr11f/qUXWDC76Y97RiSg iat-mode=0 n Bridge obfs4 94.142.246.132:8088 135C158527AA9FE9A2F26EC515EB6999D813D347 cert=wTUz0/5FhAZRkitil5MprGbSF3JzjxjxI1kAmxAdSeDy98NgcLr11f/qUXWDC76Y97RiSg iat-mode=0
n Bridge obfs4 20.102.79.78:22022 B5705F7E616DAB0F477E3E1ADC23E40413F683FE cert=1Cc/hwPtPjzFKGHVOP0j/qmBgnvquRx8+im35/u5TIYjDQ3FlMfA5VvTrQ/hbX8BZZooLQ iat-mode=0
n Bridge obfs4 152.70.180.20:1993 3327C43587E66AD5F874C4234A1D72C938AD7318 cert=s7xLRUO2psaX7TMUP2YhXdxItR4U6K7D+E3gQaS/+yWUppevtazIibq4dN1g5Reu6dD2QQ iat-mode=0 n Bridge obfs4 152.70.180.20:1993 3327C43587E66AD5F874C4234A1D72C938AD7318 cert=s7xLRUO2psaX7TMUP2YhXdxItR4U6K7D+E3gQaS/+yWUppevtazIibq4dN1g5Reu6dD2QQ iat-mode=0
n Bridge obfs4 144.202.12.254:10002 4E220F45CD404C8A3082A36326A5ED19BB8D4404 cert=iLz5YYWO4pUw7U7MRNOSvE0qO+IVeE4kVfFVWPO3coH3FmZtrkvlaTklfXxHZaCcXWBgaA iat-mode=0 n Bridge obfs4 144.202.12.254:10002 4E220F45CD404C8A3082A36326A5ED19BB8D4404 cert=iLz5YYWO4pUw7U7MRNOSvE0qO+IVeE4kVfFVWPO3coH3FmZtrkvlaTklfXxHZaCcXWBgaA iat-mode=0
n Bridge obfs4 109.14.168.159:5082 BFE1416DEFFE969581F016A4A319A87FFB26BA91 cert=n3X1CDdKBPXPIzfKh83p3ydfMzb0AD9gKC+/gIpHb7+xjjAnYO9x3LT+T/MvOIfAXxYySg iat-mode=0 n Bridge obfs4 109.14.168.159:5082 BFE1416DEFFE969581F016A4A319A87FFB26BA91 cert=n3X1CDdKBPXPIzfKh83p3ydfMzb0AD9gKC+/gIpHb7+xjjAnYO9x3LT+T/MvOIfAXxYySg iat-mode=0
n Bridge obfs4 45.150.172.16:80 82849E69CBB25EA7F479155F7DCD89D85717FF47 cert=+Krdu1jmVQOxWkMj0mqJHgwbQV49eyD6mZDS+mRExssWNHosa60g4P5Gp81sBJKzN8NrSw iat-mode=0
n Bridge obfs4 185.177.207.132:8443 4FB781F7A9DD39DA53A7996907817FC479874D19 cert=UL2gCAXWW5kEWY4TQ0lNeu6OAmzh40bXYVhMnTWVG8USnyy/zEKGSIPgmwTDMumWr9c1Pg iat-mode=0 n Bridge obfs4 185.177.207.132:8443 4FB781F7A9DD39DA53A7996907817FC479874D19 cert=UL2gCAXWW5kEWY4TQ0lNeu6OAmzh40bXYVhMnTWVG8USnyy/zEKGSIPgmwTDMumWr9c1Pg iat-mode=0
n Bridge obfs4 213.108.110.149:7499 519344140473CF91030B08F91521F9A6C144ED6C cert=k9fSL/d491qAkGmi2VeSwVlfuyO02jBeN54qxzzQISxpfm3b+a6kJpo8/Bfy1ACbHZIJUg iat-mode=0
n Bridge obfs4 158.174.114.97:3456 32665CD4CBE19092CA47A53D317B8BFF5810441C cert=ne5Zt0TcMedSGmFwAs/AV6J6E9Hn7mG5mR6vQNpEfyuCZK1VRpQvU1LvvtesSu4CXqZtYQ iat-mode=0
n Bridge obfs4 64.4.175.62:8000 8B72740D150795ACB5101AA5F95D1ACDA4FE6B3E cert=vduuNhJ5U/8hjZmllP6AFfXSlSZsnrimdR8Tm8DY9dxWS4n2j92fNc0qHihUwRqwcOfIcg iat-mode=0
n Bridge obfs4 82.64.115.17:990 B08238781C2CD80DBD95AEABEB6F6C75F2E2CEB6 cert=1udeMlFNs3sJ20zwpPE6nShZqqwDb3F1ET4KzfSfD+fktkue9zNx9H3t+yLCPAsg+6UTUA iat-mode=1
n Bridge obfs4 87.161.120.147:9292 9418EEBE8AEAE32CC381AF51610366E8B24651E0 cert=DFRm74qsD1i2/ypaGochpX6CS1j9JTFAKEYaHXrgrx6M2LG5Cvppdt3Ob7lULfhqgtAUdg iat-mode=0
n Bridge obfs4 157.90.245.231:8599 C23CD468EC04555E2B37BE81A771E681049DEA6A cert=UsmDelrbwg4jc6BMvZJ0TS8klUIa2qkbRu3xwQc3ZXPEgpMqyTYUxcVwyPbIU5KmAHsmAA iat-mode=0
v Bridge 92.243.15.235:9001 477EAD3C04036B48235F1F27FC91420A286A4B7F v Bridge 92.243.15.235:9001 477EAD3C04036B48235F1F27FC91420A286A4B7F
v Bridge 213.108.108.145:17674 A39C0FE47963B6E8CFE9815549864DE544935A31 v Bridge 213.108.108.145:17674 A39C0FE47963B6E8CFE9815549864DE544935A31
v Bridge 213.196.191.96:9060 05E222E2A8C234234FE0CEB58B08A93B8FC360DB v Bridge 213.196.191.96:9060 05E222E2A8C234234FE0CEB58B08A93B8FC360DB

View File

@@ -56,7 +56,7 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(clock).currentTimeMillis(); oneOf(clock).currentTimeMillis();
will(returnValue(timestamp - MAX_CLOCK_DIFFERENCE)); will(returnValue(timestamp - MAX_CLOCK_DIFFERENCE));
oneOf(clientHelper).toList(message, true); oneOf(clientHelper).toList(message.getBody());
will(returnValue(body)); will(returnValue(body));
oneOf(metadataEncoder).encode(dictionary); oneOf(metadataEncoder).encode(dictionary);
will(returnValue(meta)); will(returnValue(meta));
@@ -86,7 +86,7 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(clock).currentTimeMillis(); oneOf(clock).currentTimeMillis();
will(returnValue(timestamp)); will(returnValue(timestamp));
oneOf(clientHelper).toList(shortMessage, true); oneOf(clientHelper).toList(shortMessage.getBody());
will(returnValue(body)); will(returnValue(body));
oneOf(metadataEncoder).encode(dictionary); oneOf(metadataEncoder).encode(dictionary);
will(returnValue(meta)); will(returnValue(meta));
@@ -114,7 +114,7 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(clock).currentTimeMillis(); oneOf(clock).currentTimeMillis();
will(returnValue(timestamp)); will(returnValue(timestamp));
oneOf(clientHelper).toList(message, true); oneOf(clientHelper).toList(message.getBody());
will(throwException(new FormatException())); will(throwException(new FormatException()));
}}); }});
@@ -126,7 +126,7 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(clock).currentTimeMillis(); oneOf(clock).currentTimeMillis();
will(returnValue(timestamp)); will(returnValue(timestamp));
oneOf(clientHelper).toList(message, true); oneOf(clientHelper).toList(message.getBody());
will(returnValue(body)); will(returnValue(body));
}}); }});

View File

@@ -546,7 +546,7 @@ public class ClientHelperImplTest extends BrambleMockTestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(bdfReaderFactory) oneOf(bdfReaderFactory)
.createReader(with(any(InputStream.class)), with(true)); .createReader(with(any(InputStream.class)));
will(returnValue(bdfReader)); will(returnValue(bdfReader));
oneOf(bdfReader).readList(); oneOf(bdfReader).readList();
will(returnValue(list)); will(returnValue(list));

View File

@@ -1,6 +1,5 @@
package org.briarproject.bramble.data; package org.briarproject.bramble.data;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.BrambleTestCase;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -32,14 +31,11 @@ public class BdfReaderImplFuzzingTest extends BrambleTestCase {
buf[1] = 0x14; // Length 20 bytes buf[1] = 0x14; // Length 20 bytes
in.reset(); in.reset();
BdfReaderImpl r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT, BdfReaderImpl r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT,
DEFAULT_MAX_BUFFER_SIZE, true); DEFAULT_MAX_BUFFER_SIZE);
try { int length = r.readString().length();
int length = r.readString().length(); assertTrue(length >= 0);
assertTrue(length <= 20); assertTrue(length <= 20);
assertTrue(r.eof()); assertTrue(r.eof());
} catch (FormatException e) {
// Expected when bytes are not valid UTF-8
}
} }
} }
} }

View File

@@ -11,7 +11,6 @@ import java.io.ByteArrayInputStream;
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE; import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
import static org.briarproject.bramble.api.data.BdfReader.DEFAULT_MAX_BUFFER_SIZE; import static org.briarproject.bramble.api.data.BdfReader.DEFAULT_MAX_BUFFER_SIZE;
import static org.briarproject.bramble.data.BdfReaderImpl.DEFAULT_NESTED_LIMIT; import static org.briarproject.bramble.data.BdfReaderImpl.DEFAULT_NESTED_LIMIT;
import static org.briarproject.bramble.util.StringUtils.UTF_8;
import static org.briarproject.bramble.util.StringUtils.fromHexString; import static org.briarproject.bramble.util.StringUtils.fromHexString;
import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.bramble.util.StringUtils.toHexString; import static org.briarproject.bramble.util.StringUtils.toHexString;
@@ -89,18 +88,6 @@ public class BdfReaderImplTest extends BrambleTestCase {
assertTrue(r.eof()); assertTrue(r.eof());
} }
@Test(expected = FormatException.class)
public void testReadLong16CouldHaveBeenLong8Max() throws Exception {
setContents("22" + "007F");
r.readLong();
}
@Test(expected = FormatException.class)
public void testReadLong16CouldHaveBeenLong8Min() throws Exception {
setContents("22" + "FF80");
r.readLong();
}
@Test @Test
public void testSkipLong16() throws Exception { public void testSkipLong16() throws Exception {
setContents("22" + "0080"); setContents("22" + "0080");
@@ -119,18 +106,6 @@ public class BdfReaderImplTest extends BrambleTestCase {
assertTrue(r.eof()); assertTrue(r.eof());
} }
@Test(expected = FormatException.class)
public void testReadLong32CouldHaveBeenLong16Max() throws Exception {
setContents("24" + "00007FFF");
r.readLong();
}
@Test(expected = FormatException.class)
public void testReadLong32CouldHaveBeenLong16Min() throws Exception {
setContents("24" + "FFFF8000");
r.readLong();
}
@Test @Test
public void testSkipLong32() throws Exception { public void testSkipLong32() throws Exception {
setContents("24" + "00008000"); setContents("24" + "00008000");
@@ -149,48 +124,13 @@ public class BdfReaderImplTest extends BrambleTestCase {
assertTrue(r.eof()); assertTrue(r.eof());
} }
@Test(expected = FormatException.class)
public void testReadLong64CouldHaveBeenLong32Max() throws Exception {
setContents("28" + "000000007FFFFFFF");
r.readLong();
}
@Test(expected = FormatException.class)
public void testReadLong64CouldHaveBeenLong32Min() throws Exception {
setContents("28" + "FFFFFFFF80000000");
r.readLong();
}
@Test @Test
public void testSkipLong64() throws Exception { public void testSkipLong() throws Exception {
setContents("28" + "0000000080000000"); setContents("28" + "0000000080000000");
r.skipLong(); r.skipLong();
assertTrue(r.eof()); assertTrue(r.eof());
} }
@Test
public void testReadInt() throws Exception {
setContents("21" + "7F" + "21" + "80"
+ "22" + "7FFF" + "22" + "8000"
+ "24" + "7FFFFFFF" + "24" + "80000000");
assertEquals(Byte.MAX_VALUE, r.readInt());
assertEquals(Byte.MIN_VALUE, r.readInt());
assertEquals(Short.MAX_VALUE, r.readInt());
assertEquals(Short.MIN_VALUE, r.readInt());
assertEquals(Integer.MAX_VALUE, r.readInt());
assertEquals(Integer.MIN_VALUE, r.readInt());
assertTrue(r.eof());
}
@Test
public void testSkipInt() throws Exception {
setContents("21" + "7F" + "22" + "7FFF" + "24" + "7FFFFFFF");
r.skipInt();
r.skipInt();
r.skipInt();
assertTrue(r.eof());
}
@Test @Test
public void testReadDouble() throws Exception { public void testReadDouble() throws Exception {
// http://babbage.cs.qc.edu/IEEE-754/Decimal.html // http://babbage.cs.qc.edu/IEEE-754/Decimal.html
@@ -222,7 +162,7 @@ public class BdfReaderImplTest extends BrambleTestCase {
@Test @Test
public void testReadString8() throws Exception { public void testReadString8() throws Exception {
String longest = getRandomString(Byte.MAX_VALUE); String longest = getRandomString(Byte.MAX_VALUE);
String longHex = toHexString(longest.getBytes(UTF_8)); String longHex = toHexString(longest.getBytes("UTF-8"));
// "foo", the empty string, and 127 random letters // "foo", the empty string, and 127 random letters
setContents("41" + "03" + "666F6F" + "41" + "00" + setContents("41" + "03" + "666F6F" + "41" + "00" +
"41" + "7F" + longHex); "41" + "7F" + longHex);
@@ -246,7 +186,7 @@ public class BdfReaderImplTest extends BrambleTestCase {
@Test @Test
public void testSkipString8() throws Exception { public void testSkipString8() throws Exception {
String longest = getRandomString(Byte.MAX_VALUE); String longest = getRandomString(Byte.MAX_VALUE);
String longHex = toHexString(longest.getBytes(UTF_8)); String longHex = toHexString(longest.getBytes("UTF-8"));
// "foo", the empty string, and 127 random letters // "foo", the empty string, and 127 random letters
setContents("41" + "03" + "666F6F" + "41" + "00" + setContents("41" + "03" + "666F6F" + "41" + "00" +
"41" + "7F" + longHex); "41" + "7F" + longHex);
@@ -259,9 +199,9 @@ public class BdfReaderImplTest extends BrambleTestCase {
@Test @Test
public void testReadString16() throws Exception { public void testReadString16() throws Exception {
String shortest = getRandomString(Byte.MAX_VALUE + 1); String shortest = getRandomString(Byte.MAX_VALUE + 1);
String shortHex = toHexString(shortest.getBytes(UTF_8)); String shortHex = toHexString(shortest.getBytes("UTF-8"));
String longest = getRandomString(Short.MAX_VALUE); String longest = getRandomString(Short.MAX_VALUE);
String longHex = toHexString(longest.getBytes(UTF_8)); String longHex = toHexString(longest.getBytes("UTF-8"));
// 128 random letters and 2^15 -1 random letters // 128 random letters and 2^15 -1 random letters
setContents("42" + "0080" + shortHex + "42" + "7FFF" + longHex); setContents("42" + "0080" + shortHex + "42" + "7FFF" + longHex);
assertEquals(shortest, r.readString()); assertEquals(shortest, r.readString());
@@ -273,7 +213,7 @@ public class BdfReaderImplTest extends BrambleTestCase {
public void testReadString16ChecksMaxLength() throws Exception { public void testReadString16ChecksMaxLength() throws Exception {
int maxBufferSize = Byte.MAX_VALUE + 1; int maxBufferSize = Byte.MAX_VALUE + 1;
String valid = getRandomString(Byte.MAX_VALUE + 1); String valid = getRandomString(Byte.MAX_VALUE + 1);
String validHex = toHexString(valid.getBytes(UTF_8)); String validHex = toHexString(valid.getBytes("UTF-8"));
String invalidhex = validHex + "20"; String invalidhex = validHex + "20";
// 128 random letters, the same plus a space // 128 random letters, the same plus a space
setContents("42" + "0080" + validHex setContents("42" + "0080" + validHex
@@ -283,20 +223,12 @@ public class BdfReaderImplTest extends BrambleTestCase {
r.readString(); r.readString();
} }
@Test(expected = FormatException.class)
public void testReadString16CouldHaveBeenString8() throws Exception {
String longest = getRandomString(Byte.MAX_VALUE);
String longHex = toHexString(longest.getBytes(UTF_8));
setContents("42" + "007F" + longHex);
r.readString();
}
@Test @Test
public void testSkipString16() throws Exception { public void testSkipString16() throws Exception {
String shortest = getRandomString(Byte.MAX_VALUE + 1); String shortest = getRandomString(Byte.MAX_VALUE + 1);
String shortHex = toHexString(shortest.getBytes(UTF_8)); String shortHex = toHexString(shortest.getBytes("UTF-8"));
String longest = getRandomString(Short.MAX_VALUE); String longest = getRandomString(Short.MAX_VALUE);
String longHex = toHexString(longest.getBytes(UTF_8)); String longHex = toHexString(longest.getBytes("UTF-8"));
// 128 random letters and 2^15 - 1 random letters // 128 random letters and 2^15 - 1 random letters
setContents("42" + "0080" + shortHex + "42" + "7FFF" + longHex); setContents("42" + "0080" + shortHex + "42" + "7FFF" + longHex);
r.skipString(); r.skipString();
@@ -307,7 +239,7 @@ public class BdfReaderImplTest extends BrambleTestCase {
@Test @Test
public void testReadString32() throws Exception { public void testReadString32() throws Exception {
String shortest = getRandomString(Short.MAX_VALUE + 1); String shortest = getRandomString(Short.MAX_VALUE + 1);
String shortHex = toHexString(shortest.getBytes(UTF_8)); String shortHex = toHexString(shortest.getBytes("UTF-8"));
// 2^15 random letters // 2^15 random letters
setContents("44" + "00008000" + shortHex); setContents("44" + "00008000" + shortHex);
assertEquals(shortest, r.readString()); assertEquals(shortest, r.readString());
@@ -318,7 +250,7 @@ public class BdfReaderImplTest extends BrambleTestCase {
public void testReadString32ChecksMaxLength() throws Exception { public void testReadString32ChecksMaxLength() throws Exception {
int maxBufferSize = Short.MAX_VALUE + 1; int maxBufferSize = Short.MAX_VALUE + 1;
String valid = getRandomString(maxBufferSize); String valid = getRandomString(maxBufferSize);
String validHex = toHexString(valid.getBytes(UTF_8)); String validHex = toHexString(valid.getBytes("UTF-8"));
String invalidHex = validHex + "20"; String invalidHex = validHex + "20";
// 2^15 random letters, the same plus a space // 2^15 random letters, the same plus a space
setContents("44" + "00008000" + validHex + setContents("44" + "00008000" + validHex +
@@ -328,18 +260,10 @@ public class BdfReaderImplTest extends BrambleTestCase {
r.readString(); r.readString();
} }
@Test(expected = FormatException.class)
public void testReadString32CouldHaveBeenString16() throws Exception {
String longest = getRandomString(Short.MAX_VALUE);
String longHex = toHexString(longest.getBytes(UTF_8));
setContents("44" + "00007FFF" + longHex);
r.readString();
}
@Test @Test
public void testSkipString32() throws Exception { public void testSkipString32() throws Exception {
String shortest = getRandomString(Short.MAX_VALUE + 1); String shortest = getRandomString(Short.MAX_VALUE + 1);
String shortHex = toHexString(shortest.getBytes(UTF_8)); String shortHex = toHexString(shortest.getBytes("UTF-8"));
// 2^15 random letters, twice // 2^15 random letters, twice
setContents("44" + "00008000" + shortHex + setContents("44" + "00008000" + shortHex +
"44" + "00008000" + shortHex); "44" + "00008000" + shortHex);
@@ -351,7 +275,7 @@ public class BdfReaderImplTest extends BrambleTestCase {
@Test @Test
public void testReadUtf8String() throws Exception { public void testReadUtf8String() throws Exception {
String unicode = "\uFDD0\uFDD1\uFDD2\uFDD3"; String unicode = "\uFDD0\uFDD1\uFDD2\uFDD3";
String hex = toHexString(unicode.getBytes(UTF_8)); String hex = toHexString(unicode.getBytes("UTF-8"));
// STRING_8 tag, "foo", the empty string, and the test string // STRING_8 tag, "foo", the empty string, and the test string
setContents("41" + "03" + "666F6F" + "41" + "00" + "41" + "0C" + hex); setContents("41" + "03" + "666F6F" + "41" + "00" + "41" + "0C" + hex);
assertEquals("foo", r.readString()); assertEquals("foo", r.readString());
@@ -424,14 +348,6 @@ public class BdfReaderImplTest extends BrambleTestCase {
r.readRaw(); r.readRaw();
} }
@Test(expected = FormatException.class)
public void testReadRaw16CouldHaveBeenRaw8() throws Exception {
byte[] longest = new byte[Byte.MAX_VALUE];
String longHex = toHexString(longest);
setContents("52" + "007F" + longHex);
r.readRaw();
}
@Test @Test
public void testSkipRaw16() throws Exception { public void testSkipRaw16() throws Exception {
byte[] shortest = new byte[Byte.MAX_VALUE + 1]; byte[] shortest = new byte[Byte.MAX_VALUE + 1];
@@ -469,14 +385,6 @@ public class BdfReaderImplTest extends BrambleTestCase {
r.readRaw(); r.readRaw();
} }
@Test(expected = FormatException.class)
public void testReadRaw32CouldHaveBeenRaw16() throws Exception {
byte[] longest = new byte[Short.MAX_VALUE];
String longHex = toHexString(longest);
setContents("54" + "00007FFF" + longHex);
r.readRaw();
}
@Test @Test
public void testSkipRaw32() throws Exception { public void testSkipRaw32() throws Exception {
byte[] shortest = new byte[Short.MAX_VALUE + 1]; byte[] shortest = new byte[Short.MAX_VALUE + 1];
@@ -526,6 +434,25 @@ public class BdfReaderImplTest extends BrambleTestCase {
r.readList(); r.readList();
} }
@Test
public void testReadListManually() throws Exception {
// A list containing 1, "foo", and null
setContents("60" + "21" + "01" +
"41" + "03" + "666F6F" +
"00" + "80");
r.readListStart();
assertFalse(r.hasListEnd());
assertEquals(1, r.readLong());
assertFalse(r.hasListEnd());
assertEquals("foo", r.readString());
assertFalse(r.hasListEnd());
assertTrue(r.hasNull());
r.readNull();
assertTrue(r.hasListEnd());
r.readListEnd();
assertTrue(r.eof());
}
@Test @Test
public void testSkipList() throws Exception { public void testSkipList() throws Exception {
// A list containing 1, "foo", and 128 // A list containing 1, "foo", and 128
@@ -538,9 +465,9 @@ public class BdfReaderImplTest extends BrambleTestCase {
@Test @Test
public void testReadDictionary() throws Exception { public void testReadDictionary() throws Exception {
// A dictionary containing "bar" -> null and "foo" -> 123 // A dictionary containing "foo" -> 123 and "bar" -> null
setContents("70" + "41" + "03" + "626172" + "00" + setContents("70" + "41" + "03" + "666F6F" + "21" + "7B" +
"41" + "03" + "666F6F" + "21" + "7B" + "80"); "41" + "03" + "626172" + "00" + "80");
BdfDictionary dictionary = r.readDictionary(); BdfDictionary dictionary = r.readDictionary();
assertEquals(2, dictionary.size()); assertEquals(2, dictionary.size());
assertTrue(dictionary.containsKey("foo")); assertTrue(dictionary.containsKey("foo"));
@@ -590,6 +517,26 @@ public class BdfReaderImplTest extends BrambleTestCase {
r.readDictionary(); r.readDictionary();
} }
@Test
public void testReadDictionaryManually() throws Exception {
// A dictionary containing "foo" -> 123 and "bar" -> null
setContents("70" + "41" + "03" + "666F6F" + "21" + "7B" +
"41" + "03" + "626172" + "00" + "80");
r.readDictionaryStart();
assertFalse(r.hasDictionaryEnd());
assertEquals("foo", r.readString());
assertFalse(r.hasDictionaryEnd());
assertEquals(123, r.readLong());
assertFalse(r.hasDictionaryEnd());
assertEquals("bar", r.readString());
assertFalse(r.hasDictionaryEnd());
assertTrue(r.hasNull());
r.readNull();
assertTrue(r.hasDictionaryEnd());
r.readDictionaryEnd();
assertTrue(r.eof());
}
@Test @Test
public void testSkipDictionary() throws Exception { public void testSkipDictionary() throws Exception {
// A map containing "foo" -> 123 and "bar" -> null // A map containing "foo" -> 123 and "bar" -> null
@@ -610,10 +557,10 @@ public class BdfReaderImplTest extends BrambleTestCase {
@Test @Test
public void testNestedListWithinDepthLimit() throws Exception { public void testNestedListWithinDepthLimit() throws Exception {
// A list containing a list containing a list containing a list... // A list containing a list containing a list containing a list...
StringBuilder lists = new StringBuilder(); String lists = "";
for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) lists.append("60"); for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) lists += "60";
for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) lists.append("80"); for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) lists += "80";
setContents(lists.toString()); setContents(lists);
r.readList(); r.readList();
assertTrue(r.eof()); assertTrue(r.eof());
} }
@@ -621,25 +568,23 @@ public class BdfReaderImplTest extends BrambleTestCase {
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testNestedListOutsideDepthLimit() throws Exception { public void testNestedListOutsideDepthLimit() throws Exception {
// A list containing a list containing a list containing a list... // A list containing a list containing a list containing a list...
StringBuilder lists = new StringBuilder(); String lists = "";
for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) lists.append("60"); for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) lists += "60";
for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) lists.append("80"); for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) lists += "80";
setContents(lists.toString()); setContents(lists);
r.readList(); r.readList();
} }
@Test @Test
public void testNestedDictionaryWithinDepthLimit() throws Exception { public void testNestedDictionaryWithinDepthLimit() throws Exception {
// A dictionary containing a dictionary containing a dictionary... // A dictionary containing a dictionary containing a dictionary...
StringBuilder dicts = new StringBuilder(); String dicts = "";
for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) { for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++)
dicts.append("70").append("41").append("03").append("666F6F"); dicts += "70" + "41" + "03" + "666F6F";
} dicts += "11";
dicts.append("11"); for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++)
for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) { dicts += "80";
dicts.append("80"); setContents(dicts);
}
setContents(dicts.toString());
r.readDictionary(); r.readDictionary();
assertTrue(r.eof()); assertTrue(r.eof());
} }
@@ -647,15 +592,13 @@ public class BdfReaderImplTest extends BrambleTestCase {
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testNestedDictionaryOutsideDepthLimit() throws Exception { public void testNestedDictionaryOutsideDepthLimit() throws Exception {
// A dictionary containing a dictionary containing a dictionary... // A dictionary containing a dictionary containing a dictionary...
StringBuilder dicts = new StringBuilder(); String dicts = "";
for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) { for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++)
dicts.append("70").append("41").append("03").append("666F6F"); dicts += "70" + "41" + "03" + "666F6F";
} dicts += "11";
dicts.append("11"); for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++)
for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) { dicts += "80";
dicts.append("80"); setContents(dicts);
}
setContents(dicts.toString());
r.readDictionary(); r.readDictionary();
} }
@@ -682,6 +625,6 @@ public class BdfReaderImplTest extends BrambleTestCase {
private void setContents(String hex, int maxBufferSize) private void setContents(String hex, int maxBufferSize)
throws FormatException { throws FormatException {
ByteArrayInputStream in = new ByteArrayInputStream(fromHexString(hex)); ByteArrayInputStream in = new ByteArrayInputStream(fromHexString(hex));
r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT, maxBufferSize, true); r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT, maxBufferSize);
} }
} }

View File

@@ -1,80 +0,0 @@
package org.briarproject.bramble.data;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfReader;
import org.briarproject.bramble.api.data.BdfWriter;
import org.briarproject.bramble.test.BrambleTestCase;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import static org.briarproject.bramble.api.data.BdfReader.DEFAULT_MAX_BUFFER_SIZE;
import static org.briarproject.bramble.api.data.BdfReader.DEFAULT_NESTED_LIMIT;
import static org.briarproject.bramble.util.StringUtils.fromHexString;
import static org.briarproject.bramble.util.StringUtils.toHexString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class BdfReaderWriterIntegrationTest extends BrambleTestCase {
@Test
public void testConvertStringToCanonicalForm() throws Exception {
// 'foo' as a STRING_16 (not canonical, should be a STRING_8)
String hexIn = "42" + "0003" + "666F6F";
InputStream in = new ByteArrayInputStream(fromHexString(hexIn));
BdfReader r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT,
DEFAULT_MAX_BUFFER_SIZE, false); // Accept non-canonical
String s = r.readString();
assertEquals("foo", s);
assertTrue(r.eof());
// Convert the string back to BDF
ByteArrayOutputStream out = new ByteArrayOutputStream();
BdfWriter w = new BdfWriterImpl(out);
w.writeString(s);
w.flush();
String hexOut = toHexString(out.toByteArray());
// The BDF should now be in canonical form
assertEquals("41" + "03" + "666F6F", hexOut);
}
@Test
public void testConvertDictionaryToCanonicalForm() throws Exception {
// A dictionary with keys in non-canonical order: 'foo' then 'bar'
String hexIn = "70" + "41" + "03" + "666F6F" + "21" + "01"
+ "41" + "03" + "626172" + "21" + "02" + "80";
InputStream in = new ByteArrayInputStream(fromHexString(hexIn));
BdfReader r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT,
DEFAULT_MAX_BUFFER_SIZE, false); // Accept non-canonical
BdfDictionary d = r.readDictionary();
assertEquals(2, d.size());
assertTrue(r.eof());
// The entries should be returned in canonical order
Iterator<Entry<String, Object>> it = d.entrySet().iterator();
Entry<String, Object> first = it.next();
assertEquals("bar", first.getKey());
assertEquals(2L, first.getValue());
Entry<String, Object> second = it.next();
assertEquals("foo", second.getKey());
assertEquals(1L, second.getValue());
// Convert a non-canonical map to BDF (use LinkedHashMap so we know
// the entries will be iterated over in non-canonical order)
Map<String, Object> m = new LinkedHashMap<>();
m.put("foo", 1);
m.put("bar", 2);
ByteArrayOutputStream out = new ByteArrayOutputStream();
BdfWriter w = new BdfWriterImpl(out);
w.writeDictionary(m);
w.flush();
String hexOut = toHexString(out.toByteArray());
// The entries should be in canonical order: 'bar' then 'foo'
assertEquals("70" + "41" + "03" + "626172" + "21" + "02"
+ "41" + "03" + "666F6F" + "21" + "01" + "80", hexOut);
}
}

View File

@@ -1,6 +1,5 @@
package org.briarproject.bramble.data; package org.briarproject.bramble.data;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.BrambleTestCase;
import org.briarproject.bramble.util.StringUtils; import org.briarproject.bramble.util.StringUtils;
import org.junit.Test; import org.junit.Test;
@@ -169,11 +168,9 @@ public class BdfWriterImplTest extends BrambleTestCase {
@Test @Test
public void testWriteDictionary() throws IOException { public void testWriteDictionary() throws IOException {
// Add entries to dictionary in descending order - they should be // Use LinkedHashMap to get predictable iteration order
// output in ascending order. Use LinkedHashMap to get predictable
// iteration order
Map<String, Object> m = new LinkedHashMap<>(); Map<String, Object> m = new LinkedHashMap<>();
for (int i = 3; i >= 0; i--) m.put(String.valueOf(i), i); for (int i = 0; i < 4; i++) m.put(String.valueOf(i), i);
w.writeDictionary(m); w.writeDictionary(m);
// DICTIONARY tag, keys as strings and values as integers, END tag // DICTIONARY tag, keys as strings and values as integers, END tag
checkContents("70" + "41" + "01" + "30" + "21" + "00" + checkContents("70" + "41" + "01" + "30" + "21" + "00" +
@@ -183,17 +180,30 @@ public class BdfWriterImplTest extends BrambleTestCase {
} }
@Test @Test
public void testWriteBdfDictionary() throws IOException { public void testWriteDelimitedList() throws IOException {
// Add entries to dictionary in descending order - they should be w.writeListStart();
// output in ascending order w.writeLong(1);
BdfDictionary d = new BdfDictionary(); w.writeString("foo");
for (int i = 3; i >= 0; i--) d.put(String.valueOf(i), i); w.writeLong(128);
w.writeDictionary(d); w.writeListEnd();
// DICTIONARY tag, keys as strings and values as integers, END tag // LIST tag, 1 as integer, "foo" as string, 128 as integer, END tag
checkContents("70" + "41" + "01" + "30" + "21" + "00" + checkContents("60" + "21" + "01" +
"41" + "01" + "31" + "21" + "01" + "41" + "03" + "666F6F" +
"41" + "01" + "32" + "21" + "02" + "22" + "0080" + "80");
"41" + "01" + "33" + "21" + "03" + "80"); }
@Test
public void testWriteDelimitedDictionary() throws IOException {
w.writeDictionaryStart();
w.writeString("foo");
w.writeLong(123);
w.writeString("bar");
w.writeNull();
w.writeDictionaryEnd();
// DICTIONARY tag, "foo" as string, 123 as integer, "bar" as string,
// NULL tag, END tag
checkContents("70" + "41" + "03" + "666F6F" +
"21" + "7B" + "41" + "03" + "626172" + "00" + "80");
} }
@Test @Test

View File

@@ -1,6 +1,5 @@
package org.briarproject.bramble.mailbox; package org.briarproject.bramble.mailbox;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.db.TransactionManager; import org.briarproject.bramble.api.db.TransactionManager;
@@ -10,23 +9,17 @@ import org.briarproject.bramble.api.mailbox.event.OwnMailboxConnectionStatusEven
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.test.BrambleMockTestCase; import org.briarproject.bramble.test.BrambleMockTestCase;
import org.briarproject.bramble.test.DbExpectations; import org.briarproject.bramble.test.DbExpectations;
import org.briarproject.bramble.util.Base32;
import org.junit.Test; import org.junit.Test;
import java.io.IOException; import java.io.IOException;
import java.util.Locale;
import java.util.Random; import java.util.Random;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
import static org.briarproject.bramble.api.mailbox.MailboxConstants.CLIENT_SUPPORTS; import static org.briarproject.bramble.api.mailbox.MailboxConstants.CLIENT_SUPPORTS;
import static org.briarproject.bramble.test.TestUtils.getMailboxProperties; import static org.briarproject.bramble.test.TestUtils.getMailboxProperties;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.hasEvent; import static org.briarproject.bramble.test.TestUtils.hasEvent;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class MailboxManagerImplTest extends BrambleMockTestCase { public class MailboxManagerImplTest extends BrambleMockTestCase {
@@ -132,32 +125,4 @@ public class MailboxManagerImplTest extends BrambleMockTestCase {
assertTrue(manager.checkConnection()); assertTrue(manager.checkConnection());
} }
@Test
public void testConvertBase32Payload() throws FormatException {
byte[] payload = getRandomBytes(65);
String base32payload = Base32.encode(payload).toLowerCase(Locale.ROOT);
String expected = new String(payload, ISO_8859_1);
try {
manager.convertBase32Payload("foo bar");
fail();
} catch (FormatException e) {
// expected
}
try { // doesn't work with shorter link
manager.convertBase32Payload("briar-mailbox://" +
base32payload.substring(0, base32payload.length() - 1));
fail();
} catch (FormatException e) {
// expected
}
// works with white-spaces
assertEquals(expected, manager.convertBase32Payload(
"foo bar briar-mailbox://" + base32payload + " foo bar"));
// even works without white-space at the end
assertEquals(expected, manager.convertBase32Payload(
"foo bar briar-mailbox://" + base32payload + "foobar"));
// even works without schema and extra chars at end
assertEquals(expected, manager.convertBase32Payload(
"foo bar " + base32payload + "foobar"));
}
} }

View File

@@ -217,13 +217,13 @@ public class LanTcpPluginTest extends BrambleTestCase {
// The plugin should have bound a socket and stored the port number // The plugin should have bound a socket and stored the port number
BdfList descriptor = kal.getDescriptor(); BdfList descriptor = kal.getDescriptor();
assertEquals(3, descriptor.size()); assertEquals(3, descriptor.size());
assertEquals(TRANSPORT_ID_LAN, descriptor.getInt(0).intValue()); assertEquals(TRANSPORT_ID_LAN, descriptor.getLong(0).longValue());
byte[] address = descriptor.getRaw(1); byte[] address = descriptor.getRaw(1);
InetAddress addr = InetAddress.getByAddress(address); InetAddress addr = InetAddress.getByAddress(address);
assertTrue(addr instanceof Inet4Address); assertTrue(addr instanceof Inet4Address);
assertFalse(addr.isLoopbackAddress()); assertFalse(addr.isLoopbackAddress());
assertTrue(addr.isLinkLocalAddress() || addr.isSiteLocalAddress()); assertTrue(addr.isLinkLocalAddress() || addr.isSiteLocalAddress());
int port = descriptor.getInt(2); int port = descriptor.getLong(2).intValue();
assertTrue(port > 0 && port < 65536); assertTrue(port > 0 && port < 65536);
// The plugin should be listening on the port // The plugin should be listening on the port
InetSocketAddress socketAddr = new InetSocketAddress(addr, port); InetSocketAddress socketAddr = new InetSocketAddress(addr, port);

View File

@@ -404,7 +404,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
localGroup.getId()); localGroup.getId());
will(returnValue(messageMetadata)); will(returnValue(messageMetadata));
oneOf(clientHelper).getMessageAsList(txn, fooUpdateId, false); oneOf(clientHelper).getMessageAsList(txn, fooUpdateId);
will(returnValue(fooUpdate)); will(returnValue(fooUpdate));
oneOf(clientHelper).parseAndValidateTransportProperties( oneOf(clientHelper).parseAndValidateTransportProperties(
fooPropertiesDict); fooPropertiesDict);
@@ -471,7 +471,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
contactGroup2.getId()); contactGroup2.getId());
will(returnValue(messageMetadata)); will(returnValue(messageMetadata));
oneOf(clientHelper).getMessageAsList(txn, fooUpdateId, false); oneOf(clientHelper).getMessageAsList(txn, fooUpdateId);
will(returnValue(fooUpdate)); will(returnValue(fooUpdate));
oneOf(clientHelper).parseAndValidateTransportProperties( oneOf(clientHelper).parseAndValidateTransportProperties(
fooPropertiesDict); fooPropertiesDict);
@@ -526,7 +526,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
contactGroup.getId()); contactGroup.getId());
will(returnValue(messageMetadata)); will(returnValue(messageMetadata));
oneOf(clientHelper).getMessageAsList(txn, updateId, false); oneOf(clientHelper).getMessageAsList(txn, updateId);
will(returnValue(update)); will(returnValue(update));
oneOf(clientHelper).parseAndValidateTransportProperties( oneOf(clientHelper).parseAndValidateTransportProperties(
fooPropertiesDict); fooPropertiesDict);
@@ -564,7 +564,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
localGroup.getId()); localGroup.getId());
will(returnValue(messageMetadata)); will(returnValue(messageMetadata));
oneOf(clientHelper).getMessageAsList(txn, updateId, false); oneOf(clientHelper).getMessageAsList(txn, updateId);
will(returnValue(update)); will(returnValue(update));
oneOf(clientHelper).parseAndValidateTransportProperties( oneOf(clientHelper).parseAndValidateTransportProperties(
fooPropertiesDict); fooPropertiesDict);
@@ -695,8 +695,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
localGroup.getId()); localGroup.getId());
will(returnValue(localGroupMessageMetadata)); will(returnValue(localGroupMessageMetadata));
oneOf(clientHelper).getMessageAsList(txn, localGroupUpdateId, oneOf(clientHelper).getMessageAsList(txn, localGroupUpdateId);
false);
will(returnValue(oldUpdate)); will(returnValue(oldUpdate));
oneOf(clientHelper).parseAndValidateTransportProperties( oneOf(clientHelper).parseAndValidateTransportProperties(
oldPropertiesDict); oldPropertiesDict);
@@ -761,8 +760,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
localGroup.getId()); localGroup.getId());
will(returnValue(localGroupMessageMetadata)); will(returnValue(localGroupMessageMetadata));
oneOf(clientHelper).getMessageAsList(txn, localGroupUpdateId, oneOf(clientHelper).getMessageAsList(txn, localGroupUpdateId);
false);
will(returnValue(oldUpdate)); will(returnValue(oldUpdate));
oneOf(clientHelper).parseAndValidateTransportProperties( oneOf(clientHelper).parseAndValidateTransportProperties(
oldPropertiesDict); oldPropertiesDict);
@@ -821,12 +819,12 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
localGroup.getId()); localGroup.getId());
will(returnValue(messageMetadata)); will(returnValue(messageMetadata));
// Retrieve and parse the latest local properties // Retrieve and parse the latest local properties
oneOf(clientHelper).getMessageAsList(txn, fooVersion999, false); oneOf(clientHelper).getMessageAsList(txn, fooVersion999);
will(returnValue(fooUpdate)); will(returnValue(fooUpdate));
oneOf(clientHelper).parseAndValidateTransportProperties( oneOf(clientHelper).parseAndValidateTransportProperties(
fooPropertiesDict); fooPropertiesDict);
will(returnValue(fooProperties)); will(returnValue(fooProperties));
oneOf(clientHelper).getMessageAsList(txn, barVersion3, false); oneOf(clientHelper).getMessageAsList(txn, barVersion3);
will(returnValue(barUpdate)); will(returnValue(barUpdate));
oneOf(clientHelper).parseAndValidateTransportProperties( oneOf(clientHelper).parseAndValidateTransportProperties(
barPropertiesDict); barPropertiesDict);

View File

@@ -6,18 +6,13 @@ import org.briarproject.bramble.api.UniqueId;
import org.briarproject.bramble.api.record.Record; import org.briarproject.bramble.api.record.Record;
import org.briarproject.bramble.api.record.RecordReader; import org.briarproject.bramble.api.record.RecordReader;
import org.briarproject.bramble.api.sync.Ack; import org.briarproject.bramble.api.sync.Ack;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageFactory; import org.briarproject.bramble.api.sync.MessageFactory;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.sync.Offer; import org.briarproject.bramble.api.sync.Offer;
import org.briarproject.bramble.api.sync.Priority; import org.briarproject.bramble.api.sync.Priority;
import org.briarproject.bramble.api.sync.Request; import org.briarproject.bramble.api.sync.Request;
import org.briarproject.bramble.api.sync.SyncRecordReader; import org.briarproject.bramble.api.sync.SyncRecordReader;
import org.briarproject.bramble.api.sync.Versions; import org.briarproject.bramble.api.sync.Versions;
import org.briarproject.bramble.test.BrambleMockTestCase; import org.briarproject.bramble.test.BrambleMockTestCase;
import org.briarproject.bramble.test.PredicateMatcher;
import org.hamcrest.Matcher;
import org.jmock.Expectations; import org.jmock.Expectations;
import org.junit.Test; import org.junit.Test;
@@ -28,15 +23,12 @@ import javax.annotation.Nullable;
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES; import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
import static org.briarproject.bramble.api.sync.RecordTypes.ACK; import static org.briarproject.bramble.api.sync.RecordTypes.ACK;
import static org.briarproject.bramble.api.sync.RecordTypes.MESSAGE;
import static org.briarproject.bramble.api.sync.RecordTypes.OFFER; import static org.briarproject.bramble.api.sync.RecordTypes.OFFER;
import static org.briarproject.bramble.api.sync.RecordTypes.PRIORITY; import static org.briarproject.bramble.api.sync.RecordTypes.PRIORITY;
import static org.briarproject.bramble.api.sync.RecordTypes.REQUEST; import static org.briarproject.bramble.api.sync.RecordTypes.REQUEST;
import static org.briarproject.bramble.api.sync.RecordTypes.VERSIONS; import static org.briarproject.bramble.api.sync.RecordTypes.VERSIONS;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS; import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_SUPPORTED_VERSIONS; import static org.briarproject.bramble.api.sync.SyncConstants.MAX_SUPPORTED_VERSIONS;
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.PRIORITY_NONCE_BYTES; import static org.briarproject.bramble.api.sync.SyncConstants.PRIORITY_NONCE_BYTES;
import static org.briarproject.bramble.api.sync.SyncConstants.PROTOCOL_VERSION; import static org.briarproject.bramble.api.sync.SyncConstants.PROTOCOL_VERSION;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
@@ -54,38 +46,6 @@ public class SyncRecordReaderImplTest extends BrambleMockTestCase {
private final SyncRecordReader reader = private final SyncRecordReader reader =
new SyncRecordReaderImpl(messageFactory, recordReader); new SyncRecordReaderImpl(messageFactory, recordReader);
@Test
public void testNoFormatExceptionIfMessageIsMinimumSize() throws Exception {
expectReadRecord(createMessage(MESSAGE_HEADER_LENGTH + 1));
expectCreateMessage(1);
reader.readMessage();
}
@Test(expected = FormatException.class)
public void testFormatExceptionIfMessageIsTooSmall() throws Exception {
expectReadRecord(createMessage(MESSAGE_HEADER_LENGTH));
reader.readMessage();
}
@Test
public void testNoFormatExceptionIfMessageIsMaximumSize() throws Exception {
expectReadRecord(createMessage(MESSAGE_HEADER_LENGTH
+ MAX_MESSAGE_BODY_LENGTH));
expectCreateMessage(MAX_MESSAGE_BODY_LENGTH);
reader.readMessage();
}
@Test(expected = FormatException.class)
public void testFormatExceptionIfMessageIsTooLarge() throws Exception {
expectReadRecord(createMessage(MESSAGE_HEADER_LENGTH
+ MAX_MESSAGE_BODY_LENGTH + 1));
reader.readMessage();
}
@Test @Test
public void testNoFormatExceptionIfAckIsMaximumSize() throws Exception { public void testNoFormatExceptionIfAckIsMaximumSize() throws Exception {
expectReadRecord(createAck()); expectReadRecord(createAck());
@@ -198,20 +158,6 @@ public class SyncRecordReaderImplTest extends BrambleMockTestCase {
assertTrue(reader.eof()); assertTrue(reader.eof());
} }
private void expectCreateMessage(int bodyLength) {
MessageId messageId = new MessageId(getRandomId());
GroupId groupId = new GroupId(getRandomId());
long timestamp = System.currentTimeMillis();
context.checking(new Expectations() {{
Matcher<byte[]> matcher = new PredicateMatcher<>(byte[].class,
b -> b.length == MESSAGE_HEADER_LENGTH + bodyLength);
oneOf(messageFactory).createMessage(with(matcher));
will(returnValue(new Message(messageId, groupId, timestamp,
new byte[bodyLength])));
}});
}
private void expectReadRecord(@Nullable Record record) throws Exception { private void expectReadRecord(@Nullable Record record) throws Exception {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
//noinspection unchecked //noinspection unchecked
@@ -221,10 +167,6 @@ public class SyncRecordReaderImplTest extends BrambleMockTestCase {
}}); }});
} }
private Record createMessage(int payloadLength) {
return new Record(PROTOCOL_VERSION, MESSAGE, new byte[payloadLength]);
}
private Record createAck() throws Exception { private Record createAck() throws Exception {
return new Record(PROTOCOL_VERSION, ACK, createPayload()); return new Record(PROTOCOL_VERSION, ACK, createPayload());
} }

View File

@@ -10,8 +10,6 @@ import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import static java.lang.Double.compare;
import static java.lang.Double.parseDouble;
import static org.briarproject.bramble.test.UTest.Result.INCONCLUSIVE; import static org.briarproject.bramble.test.UTest.Result.INCONCLUSIVE;
import static org.briarproject.bramble.test.UTest.Result.LARGER; import static org.briarproject.bramble.test.UTest.Result.LARGER;
import static org.briarproject.bramble.test.UTest.Result.SMALLER; import static org.briarproject.bramble.test.UTest.Result.SMALLER;
@@ -136,7 +134,7 @@ public class UTest {
if (nA < 5 || nB < 5) die("Too few values for U test\n"); if (nA < 5 || nB < 5) die("Too few values for U test\n");
double zCritical; double zCritical;
if (args.length == 3) zCritical = parseDouble(args[2]); if (args.length == 3) zCritical = Double.valueOf(args[2]);
else zCritical = Z_CRITICAL_0_01; else zCritical = Z_CRITICAL_0_01;
switch (test(a, b, zCritical)) { switch (test(a, b, zCritical)) {
@@ -163,7 +161,7 @@ public class UTest {
BufferedReader in; BufferedReader in;
in = new BufferedReader(new FileReader(filename)); in = new BufferedReader(new FileReader(filename));
String s; String s;
while ((s = in.readLine()) != null) values.add(parseDouble(s)); while ((s = in.readLine()) != null) values.add(new Double(s));
in.close(); in.close();
} catch (FileNotFoundException fnf) { } catch (FileNotFoundException fnf) {
die(filename + " not found"); die(filename + " not found");
@@ -189,7 +187,9 @@ public class UTest {
@Override @Override
public int compareTo(@Nonnull Value v) { public int compareTo(@Nonnull Value v) {
return compare(value, v.value); if (value < v.value) return -1;
if (value > v.value) return 1;
return 0;
} }
} }
} }

View File

@@ -88,58 +88,51 @@ public class StringUtilsTest extends BrambleTestCase {
} }
@Test @Test
public void testFromUtf8AcceptsNullCharacterUsingStandardUtf8() public void testFromUtf8AcceptsNullCharacterUsingStandardUtf8() {
throws Exception {
// The UTF-8 encoding of the null character is valid // The UTF-8 encoding of the null character is valid
byte[] utf8 = new byte[1]; assertEquals("\u0000", StringUtils.fromUtf8(new byte[1]));
String actual = StringUtils.fromUtf8(utf8);
assertEquals("\u0000", actual);
// When we convert back to UTF-8 we should get the original encoding
assertArrayEquals(utf8, StringUtils.toUtf8(actual));
} }
@Test(expected = FormatException.class) @Test
public void testFromUtf8RejectsNullCharacterUsingModifiedUtf8() public void testFromUtf8RemovesNullCharacterUsingModifiedUtf8() {
throws Exception {
// The modified UTF-8 encoding of the null character is not valid // The modified UTF-8 encoding of the null character is not valid
byte[] b = new byte[] { byte[] b = new byte[] {
(byte) 0xC0, (byte) 0x80, // Null character as modified UTF-8 (byte) 0xC0, (byte) 0x80, // Null character as modified UTF-8
(byte) 0xC8, (byte) 0x85 // U+0205 (byte) 0xC8, (byte) 0x85 // U+0205
}; };
StringUtils.fromUtf8(b); // Conversion should ignore the invalid character and return the rest
String expected = "\u0205";
assertEquals(expected, StringUtils.fromUtf8(b));
} }
@Test @Test
public void testFromUtf8AcceptsSupplementaryCharacterUsingStandardUtf8() public void testFromUtf8AcceptsSupplementaryCharacterUsingStandardUtf8() {
throws Exception {
// The UTF-8 encoding of a supplementary character is valid and should // The UTF-8 encoding of a supplementary character is valid and should
// be converted to a surrogate pair // be converted to a surrogate pair
byte[] utf8 = new byte[] { byte[] b = new byte[] {
(byte) 0xF0, (byte) 0x90, (byte) 0x90, (byte) 0x80, // U+10400 (byte) 0xF0, (byte) 0x90, (byte) 0x90, (byte) 0x80, // U+10400
(byte) 0xC8, (byte) 0x85 // U+0205 (byte) 0xC8, (byte) 0x85 // U+0205
}; };
String expected = "\uD801\uDC00\u0205"; // Surrogate pair String expected = "\uD801\uDC00\u0205"; // Surrogate pair
String actual = StringUtils.fromUtf8(utf8); assertEquals(expected, StringUtils.fromUtf8(b));
assertEquals(expected, actual);
// When we convert back to UTF-8 we should get the original encoding
assertArrayEquals(utf8, StringUtils.toUtf8(actual));
} }
@Test(expected = FormatException.class) @Test
public void testFromUtf8RejectsSupplementaryCharacterUsingModifiedUtf8() public void testFromUtf8RemovesSupplementaryCharacterUsingModifiedUtf8() {
throws Exception {
// The CESU-8 or modified UTF-8 encoding of a supplementary character // The CESU-8 or modified UTF-8 encoding of a supplementary character
// is not valid // is not valid
byte[] utf8 = new byte[] { byte[] b = new byte[] {
(byte) 0xED, (byte) 0xA0, (byte) 0x81, // U+10400 as CSEU-8 (byte) 0xED, (byte) 0xA0, (byte) 0x81, // U+10400 as CSEU-8
(byte) 0xED, (byte) 0xB0, (byte) 0x80, (byte) 0xED, (byte) 0xB0, (byte) 0x80,
(byte) 0xC8, (byte) 0x85 // U+0205 (byte) 0xC8, (byte) 0x85 // U+0205
}; };
StringUtils.fromUtf8(utf8); // Conversion should ignore the invalid character and return the rest
String expected = "\u0205";
assertEquals(expected, StringUtils.fromUtf8(b));
} }
@Test @Test
public void testFromUtf8EmptyInput() throws Exception { public void testFromUtf8EmptyInput() {
assertEquals("", StringUtils.fromUtf8(new byte[0])); assertEquals("", StringUtils.fromUtf8(new byte[0]));
} }

View File

@@ -7,17 +7,24 @@ apply plugin: 'witness'
apply from: 'witness.gradle' apply from: 'witness.gradle'
apply from: '../dagger.gradle' apply from: '../dagger.gradle'
configurations {
tor
}
dependencies { dependencies {
implementation project(':bramble-core') implementation project(':bramble-core')
implementation fileTree(dir: 'libs', include: '*.jar') implementation fileTree(dir: 'libs', include: '*.jar')
def jna_version = '5.10.0' def jna_version = '4.5.2'
implementation "net.java.dev.jna:jna:$jna_version" implementation "net.java.dev.jna:jna:$jna_version"
implementation "net.java.dev.jna:jna-platform:$jna_version" implementation "net.java.dev.jna:jna-platform:$jna_version"
testImplementation "org.briarproject:tor-linux:$tor_version" tor "org.briarproject:tor-linux:$tor_version"
testImplementation "org.briarproject:obfs4proxy-linux:$obfs4proxy_version" tor "org.briarproject:tor-windows:$tor_version"
testImplementation "org.briarproject:snowflake-linux:$snowflake_version" tor "org.briarproject:obfs4proxy-linux:$obfs4proxy_version"
tor "org.briarproject:obfs4proxy-windows:$obfs4proxy_version"
tor "org.briarproject:snowflake-linux:$snowflake_version"
tor "org.briarproject:snowflake-windows:$snowflake_version"
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version" annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
@@ -32,6 +39,31 @@ dependencies {
testAnnotationProcessor "com.google.dagger:dagger-compiler:$dagger_version" testAnnotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
} }
def torBinariesDir = 'src/main/resources'
task cleanTorBinaries {
doLast {
delete fileTree(torBinariesDir) { include '*.zip' }
}
}
clean.dependsOn cleanTorBinaries
task unpackTorBinaries {
doLast {
copy {
from configurations.tor.collect { zipTree(it) }
into torBinariesDir
}
}
dependsOn cleanTorBinaries
}
processResources {
inputs.dir torBinariesDir
dependsOn unpackTorBinaries
}
tasks.withType(Test) { tasks.withType(Test) {
systemProperty 'java.library.path', 'libs' systemProperty 'java.library.path', 'libs'
} }

View File

@@ -53,7 +53,7 @@ class UnixTorPlugin extends JavaTorPlugin {
private interface CLibrary extends Library { private interface CLibrary extends Library {
CLibrary INSTANCE = Native.load("c", CLibrary.class); CLibrary INSTANCE = Native.loadLibrary("c", CLibrary.class);
int getpid(); int getpid();
} }

View File

@@ -27,7 +27,6 @@ import javax.net.SocketFactory;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static org.briarproject.bramble.util.OsUtils.isLinux; import static org.briarproject.bramble.util.OsUtils.isLinux;
import static org.briarproject.bramble.util.OsUtils.isMac;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
@@ -58,18 +57,14 @@ public class UnixTorPluginFactory extends TorPluginFactory {
@Nullable @Nullable
@Override @Override
String getArchitectureForTorBinary() { String getArchitectureForTorBinary() {
if (!isLinux() && !isMac()) return null; if (!isLinux()) return null;
String arch = System.getProperty("os.arch"); String arch = System.getProperty("os.arch");
if (LOG.isLoggable(INFO)) { if (LOG.isLoggable(INFO)) {
LOG.info("System's os.arch is " + arch); LOG.info("System's os.arch is " + arch);
} }
if (isLinux()) { if (arch.equals("amd64")) return "linux-x86_64";
if (arch.equals("amd64")) return "x86_64"; else if (arch.equals("aarch64")) return "linux-aarch64";
else if (arch.equals("aarch64")) return "aarch64"; else if (arch.equals("arm")) return "linux-armhf";
else if (arch.equals("arm")) return "armhf";
} else if (isMac()) {
return "any";
}
return null; return null;
} }

View File

@@ -94,8 +94,4 @@ class WindowsTorPlugin extends JavaTorPlugin {
if (!success.take()) throw new PluginException(); if (!success.take()) throw new PluginException();
} }
@Override
protected String getExecutableExtension() {
return ".exe";
}
} }

View File

@@ -62,7 +62,7 @@ public class WindowsTorPluginFactory extends TorPluginFactory {
if (LOG.isLoggable(INFO)) { if (LOG.isLoggable(INFO)) {
LOG.info("System's os.arch is " + arch); LOG.info("System's os.arch is " + arch);
} }
if (arch.equals("amd64")) return "x86_64"; if (arch.equals("amd64")) return "windows-x86_64";
return null; return null;
} }

View File

@@ -1,40 +0,0 @@
package org.briarproject.bramble.test;
import org.briarproject.bramble.util.OsUtils;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assume.assumeTrue;
public class TestResources {
@Before
public void isRunningOnLinux() {
assumeTrue(OsUtils.isLinux());
}
@Test
public void canReadTorLinux() {
InputStream input = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("x86_64/tor");
assertNotNull(input);
}
@Test
public void canReadObfs4ProxyLinux() {
InputStream input = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("x86_64/obfs4proxy");
assertNotNull(input);
}
@Test
public void canReadSnowflakeLinux() {
InputStream input = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("x86_64/snowflake");
assertNotNull(input);
}
}

View File

@@ -21,14 +21,17 @@ dependencyVerification {
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff', 'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3', 'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
'net.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11', 'net.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11',
'net.java.dev.jna:jna-platform:5.10.0:jna-platform-5.10.0.jar:1f71afd977051bf0109ef5e3767d4e2afd777be894d89788cc0f38ad68f6a16f', 'net.java.dev.jna:jna-platform:4.5.2:jna-platform-4.5.2.jar:f1d00c167d8921c6e23c626ef9f1c3ae0be473c95c68ffa012bc7ae55a87e2d6',
'net.java.dev.jna:jna:5.10.0:jna-5.10.0.jar:e335c10679f743207d822c5f7948e930319835492575a9dba6b94f8a3b96fcc8', 'net.java.dev.jna:jna:4.5.2:jna-4.5.2.jar:0c8eb7acf67261656d79005191debaba3b6bf5dd60a43735a245429381dbecff',
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0', 'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd', 'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047', 'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
'org.briarproject:obfs4proxy-linux:0.0.14:obfs4proxy-linux-0.0.14.jar:6391d323d45a279362236c7c62e21b903d07d4f31f5e0c8d49d009769b720cc6', 'org.briarproject:obfs4proxy-linux:0.0.14-tor1:obfs4proxy-linux-0.0.14-tor1.jar:9783b9c7ec588a5246f534a9c5782783c8c9821825f81c3e0c6f1ecee61cfcbb',
'org.briarproject:snowflake-linux:2.5.1:snowflake-linux-2.5.1.jar:edc807dcb7758365970d95525e4749349a27f462d0e2df6505ad1ca65fb296d2', 'org.briarproject:obfs4proxy-windows:0.0.14-tor1:obfs4proxy-windows-0.0.14-tor1.jar:9dd122b31b3cd1616f168091dcdb01de049d1e052fe5c089b7627618a8a2694b',
'org.briarproject:snowflake-linux:2.3.1:snowflake-linux-2.3.1.jar:99ecf4546d8f79eb8408168c09380fec596558ac934554bf7d4247ea7ef2c9f3',
'org.briarproject:snowflake-windows:2.3.1:snowflake-windows-2.3.1.jar:d011f1a72c00a221f56380c19aad8ff11db8c2bb1adb0784125572d80b4d275a',
'org.briarproject:tor-linux:0.4.7.13:tor-linux-0.4.7.13.jar:9819ee973cbcdc133f7d04aef9d4b957a35087627a790e532142d15412a9636f', 'org.briarproject:tor-linux:0.4.7.13:tor-linux-0.4.7.13.jar:9819ee973cbcdc133f7d04aef9d4b957a35087627a790e532142d15412a9636f',
'org.briarproject:tor-windows:0.4.7.13:tor-windows-0.4.7.13.jar:853d2769665614e26703cbe02e43b218b064c04a0bcd120fdc459cda45bd2606',
'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a', 'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a',
'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb', 'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb',
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9', 'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',

View File

@@ -26,8 +26,8 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 31 targetSdkVersion 31
versionCode 10423 versionCode 10420
versionName "1.4.23" versionName "1.4.20"
applicationId "org.briarproject.briar.android" applicationId "org.briarproject.briar.android"
buildConfigField "String", "TorVersion", "\"$tor_version\"" buildConfigField "String", "TorVersion", "\"$tor_version\""

View File

@@ -65,8 +65,7 @@ public class SetPasswordFragment extends SetupFragment {
if (!viewModel.needToShowDozeFragment()) { if (!viewModel.needToShowDozeFragment()) {
nextButton.setText(R.string.create_account_button); nextButton.setText(R.string.create_account_button);
int options = passwordConfirmation.getImeOptions(); passwordConfirmation.setImeOptions(IME_ACTION_DONE);
passwordConfirmation.setImeOptions(options | IME_ACTION_DONE);
} }
viewModel.getIsCreatingAccount() viewModel.getIsCreatingAccount()

View File

@@ -5,25 +5,16 @@ import android.os.Bundle;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.activity.BriarActivity; import org.briarproject.briar.android.activity.BriarActivity;
import org.briarproject.briar.android.blog.RssImportResult.FileImportError;
import org.briarproject.briar.android.blog.RssImportResult.FileImportSuccess;
import org.briarproject.briar.android.blog.RssImportResult.UrlImportError;
import org.briarproject.briar.android.blog.RssImportResult.UrlImportSuccess;
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener; import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
import org.briarproject.briar.android.fragment.ErrorFragment;
import org.briarproject.nullsafety.MethodsNotNullByDefault; import org.briarproject.nullsafety.MethodsNotNullByDefault;
import org.briarproject.nullsafety.ParametersNotNullByDefault; import org.briarproject.nullsafety.ParametersNotNullByDefault;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import static androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE;
import static org.briarproject.briar.android.util.UiUtils.showFragment;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
public class RssFeedActivity extends BriarActivity public class RssFeedActivity extends BriarActivity
@@ -54,29 +45,21 @@ public class RssFeedActivity extends BriarActivity
viewModel.getImportResult().observeEvent(this, this::onImportResult); viewModel.getImportResult().observeEvent(this, this::onImportResult);
} }
private void onImportResult(@Nullable RssImportResult result) { private void onImportResult(boolean result) {
FragmentManager fm = getSupportFragmentManager(); if (result) {
if (result instanceof UrlImportSuccess) { FragmentManager fm = getSupportFragmentManager();
if (fm.findFragmentByTag(RssFeedImportFragment.TAG) != null) { if (fm.findFragmentByTag(RssFeedImportFragment.TAG) != null) {
onBackPressed(); onBackPressed();
} }
} else if (result instanceof UrlImportError) { } else {
String url = ((UrlImportError) result).url; String url = viewModel.getUrlFailedImport();
if (url == null) {
throw new AssertionError();
}
RssFeedImportFailedDialogFragment dialog = RssFeedImportFailedDialogFragment dialog =
RssFeedImportFailedDialogFragment.newInstance(url); RssFeedImportFailedDialogFragment.newInstance(url);
dialog.show(fm, RssFeedImportFailedDialogFragment.TAG); dialog.show(getSupportFragmentManager(),
} else if (result instanceof FileImportSuccess) { RssFeedImportFailedDialogFragment.TAG);
// pop stack back to before the initial import fragment
fm.popBackStackImmediate(RssFeedImportFragment.TAG,
POP_BACK_STACK_INCLUSIVE);
} else if (result instanceof FileImportError) {
// pop stack back to initial import fragment
fm.popBackStackImmediate(RssFeedImportFragment.TAG, 0);
// show error fragment
Fragment f = ErrorFragment.newInstance(
getString(R.string.blogs_rss_feeds_import_error));
String tag = ErrorFragment.TAG;
showFragment(fm, f, tag);
} }
} }
} }

View File

@@ -1,13 +1,9 @@
package org.briarproject.briar.android.blog; package org.briarproject.briar.android.blog;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
@@ -17,27 +13,18 @@ import android.widget.ProgressBar;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.fragment.BaseFragment; import org.briarproject.briar.android.fragment.BaseFragment;
import org.briarproject.briar.android.fragment.ProgressFragment;
import org.briarproject.briar.android.util.ActivityLaunchers.GetContentAdvanced;
import org.briarproject.briar.android.util.ActivityLaunchers.OpenDocumentAdvanced;
import org.briarproject.nullsafety.MethodsNotNullByDefault; import org.briarproject.nullsafety.MethodsNotNullByDefault;
import org.briarproject.nullsafety.ParametersNotNullByDefault; import org.briarproject.nullsafety.ParametersNotNullByDefault;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.RequiresApi;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import static android.os.Build.VERSION.SDK_INT;
import static android.view.View.GONE; import static android.view.View.GONE;
import static android.view.View.VISIBLE; import static android.view.View.VISIBLE;
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE; import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard; import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard;
import static org.briarproject.briar.android.util.UiUtils.launchActivityToOpenFile;
import static org.briarproject.briar.android.util.UiUtils.showFragment;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
@@ -52,15 +39,6 @@ public class RssFeedImportFragment extends BaseFragment {
private Button importButton; private Button importButton;
private ProgressBar progressBar; private ProgressBar progressBar;
@RequiresApi(19)
private final ActivityResultLauncher<String[]> docLauncher =
registerForActivityResult(new OpenDocumentAdvanced(),
this::onFileChosen);
private final ActivityResultLauncher<String> contentLauncher =
registerForActivityResult(new GetContentAdvanced(),
this::onFileChosen);
@Override @Override
public void injectFragment(ActivityComponent component) { public void injectFragment(ActivityComponent component) {
component.inject(this); component.inject(this);
@@ -74,7 +52,6 @@ public class RssFeedImportFragment extends BaseFragment {
@Nullable ViewGroup container, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) { @Nullable Bundle savedInstanceState) {
requireActivity().setTitle(getString(R.string.blogs_rss_feeds_import)); requireActivity().setTitle(getString(R.string.blogs_rss_feeds_import));
if (SDK_INT >= 19) setHasOptionsMenu(true);
View v = inflater.inflate(R.layout.fragment_rss_feed_import, View v = inflater.inflate(R.layout.fragment_rss_feed_import,
container, false); container, false);
@@ -115,40 +92,11 @@ public class RssFeedImportFragment extends BaseFragment {
return v; return v;
} }
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (SDK_INT >= 19) {
inflater.inflate(R.menu.rss_feed_import_actions, menu);
}
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_import_file && SDK_INT >= 19) {
launchActivityToOpenFile(requireContext(), docLauncher,
contentLauncher, "*/*");
return true;
}
return super.onOptionsItemSelected(item);
}
@Override @Override
public String getUniqueTag() { public String getUniqueTag() {
return TAG; return TAG;
} }
private void onFileChosen(@Nullable Uri uri) {
if (uri == null) return;
// show progress fragment
Fragment f = ProgressFragment.newInstance(
getString(R.string.blogs_rss_feeds_import_progress));
String tag = ProgressFragment.TAG;
showFragment(getParentFragmentManager(), f, tag);
// view model will import and change state that activity will react to
viewModel.importFeed(uri);
}
private void enableOrDisableImportButton() { private void enableOrDisableImportButton() {
String url = urlInput.getText().toString(); String url = urlInput.getText().toString();
importButton.setEnabled(viewModel.validateAndNormaliseUrl(url) != null); importButton.setEnabled(viewModel.validateAndNormaliseUrl(url) != null);

View File

@@ -1,8 +1,6 @@
package org.briarproject.briar.android.blog; package org.briarproject.briar.android.blog;
import android.app.Application; import android.app.Application;
import android.content.ContentResolver;
import android.net.Uri;
import android.util.Patterns; import android.util.Patterns;
import org.briarproject.bramble.api.db.DatabaseExecutor; import org.briarproject.bramble.api.db.DatabaseExecutor;
@@ -13,10 +11,6 @@ import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.briar.android.blog.RssImportResult.FileImportError;
import org.briarproject.briar.android.blog.RssImportResult.FileImportSuccess;
import org.briarproject.briar.android.blog.RssImportResult.UrlImportError;
import org.briarproject.briar.android.blog.RssImportResult.UrlImportSuccess;
import org.briarproject.briar.android.viewmodel.DbViewModel; import org.briarproject.briar.android.viewmodel.DbViewModel;
import org.briarproject.briar.android.viewmodel.LiveEvent; import org.briarproject.briar.android.viewmodel.LiveEvent;
import org.briarproject.briar.android.viewmodel.LiveResult; import org.briarproject.briar.android.viewmodel.LiveResult;
@@ -26,7 +20,6 @@ import org.briarproject.briar.api.feed.FeedManager;
import org.briarproject.nullsafety.NotNullByDefault; import org.briarproject.nullsafety.NotNullByDefault;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
@@ -37,7 +30,6 @@ import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
@@ -60,9 +52,11 @@ class RssFeedViewModel extends DbViewModel {
private final MutableLiveData<LiveResult<List<Feed>>> feeds = private final MutableLiveData<LiveResult<List<Feed>>> feeds =
new MutableLiveData<>(); new MutableLiveData<>();
@Nullable
private volatile String urlFailedImport = null;
private final MutableLiveData<Boolean> isImporting = private final MutableLiveData<Boolean> isImporting =
new MutableLiveData<>(false); new MutableLiveData<>(false);
private final MutableLiveEvent<RssImportResult> importResult = private final MutableLiveEvent<Boolean> importResult =
new MutableLiveEvent<>(); new MutableLiveEvent<>();
@Inject @Inject
@@ -126,7 +120,7 @@ class RssFeedViewModel extends DbViewModel {
}); });
} }
LiveEvent<RssImportResult> getImportResult() { LiveEvent<Boolean> getImportResult() {
return importResult; return importResult;
} }
@@ -136,6 +130,7 @@ class RssFeedViewModel extends DbViewModel {
void importFeed(String url) { void importFeed(String url) {
isImporting.setValue(true); isImporting.setValue(true);
urlFailedImport = null;
ioExecutor.execute(() -> { ioExecutor.execute(() -> {
try { try {
Feed feed = feedManager.addFeed(url); Feed feed = feedManager.addFeed(url);
@@ -150,38 +145,19 @@ class RssFeedViewModel extends DbViewModel {
updated = feedList; updated = feedList;
} }
feeds.postValue(new LiveResult<>(updated)); feeds.postValue(new LiveResult<>(updated));
importResult.postEvent(new UrlImportSuccess()); importResult.postEvent(true);
} catch (DbException | IOException e) { } catch (DbException | IOException e) {
logException(LOG, WARNING, e); logException(LOG, WARNING, e);
importResult.postEvent(new UrlImportError(url)); urlFailedImport = url;
importResult.postEvent(false);
} finally { } finally {
isImporting.postValue(false); isImporting.postValue(false);
} }
}); });
} }
@UiThread @Nullable
void importFeed(Uri uri) { String getUrlFailedImport() {
ContentResolver contentResolver = getApplication().getContentResolver(); return urlFailedImport;
ioExecutor.execute(() -> {
try (InputStream is = contentResolver.openInputStream(uri)) {
Feed feed = feedManager.addFeed(is);
// Update the feed if it was already present
List<Feed> feedList = getList(feeds);
if (feedList == null) feedList = new ArrayList<>();
List<Feed> updated = updateListItems(feedList,
f -> f.equals(feed), f -> feed);
// Add the feed if it wasn't already present
if (updated == null) {
feedList.add(feed);
updated = feedList;
}
feeds.postValue(new LiveResult<>(updated));
importResult.postEvent(new FileImportSuccess());
} catch (IOException | DbException e) {
logException(LOG, WARNING, e);
importResult.postEvent(new FileImportError());
}
});
} }
} }

View File

@@ -1,24 +0,0 @@
package org.briarproject.briar.android.blog;
import org.briarproject.nullsafety.NotNullByDefault;
@NotNullByDefault
abstract class RssImportResult {
static class UrlImportSuccess extends RssImportResult {
}
static class UrlImportError extends RssImportResult {
final String url;
UrlImportError(String url) {
this.url = url;
}
}
static class FileImportSuccess extends RssImportResult {
}
static class FileImportError extends RssImportResult {
}
}

View File

@@ -171,7 +171,7 @@ public class NicknameFragment extends BaseFragment {
private void handleExistingContact(String name, Author existing) { private void handleExistingContact(String name, Author existing) {
OnClickListener listener = (d, w) -> { OnClickListener listener = (d, w) -> {
d.dismiss(); d.dismiss();
String str = getString(R.string.contact_already_exists_general); String str = getString(R.string.contact_already_exists, name);
Toast.makeText(getContext(), str, LENGTH_LONG).show(); Toast.makeText(getContext(), str, LENGTH_LONG).show();
finish(); finish();
}; };

View File

@@ -1,58 +0,0 @@
package org.briarproject.briar.android.fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.briarproject.briar.R;
import org.briarproject.nullsafety.MethodsNotNullByDefault;
import org.briarproject.nullsafety.ParametersNotNullByDefault;
import androidx.annotation.Nullable;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class ProgressFragment extends BaseFragment {
public static final String TAG = ProgressFragment.class.getName();
private static final String PROGRESS_MSG = "progressMessage";
public static ProgressFragment newInstance(String message) {
ProgressFragment f = new ProgressFragment();
Bundle args = new Bundle();
args.putString(PROGRESS_MSG, message);
f.setArguments(args);
return f;
}
private String progressMessage;
@Override
public String getUniqueTag() {
return TAG;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = requireArguments();
progressMessage = args.getString(PROGRESS_MSG);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View v = inflater
.inflate(R.layout.fragment_progress, container, false);
TextView msg = v.findViewById(R.id.progressMessage);
msg.setText(progressMessage);
return v;
}
}

View File

@@ -145,7 +145,19 @@ public class MailboxStatusFragment extends Fragment {
@DrawableRes int iconRes; @DrawableRes int iconRes;
String title; String title;
String message = null; String message = null;
if (status.getMailboxCompatibility() < 0) { if (status.hasProblem(System.currentTimeMillis())) {
tintRes = R.color.briar_red_500;
title = getString(R.string.mailbox_status_failure_title);
iconRes = R.drawable.alerts_and_states_error;
showUnlinkWarning = false;
wizardButton.setVisibility(VISIBLE);
} else if (status.getAttemptsSinceSuccess() > 0) {
iconRes = R.drawable.ic_help_outline_white;
title = getString(R.string.mailbox_status_problem_title);
tintRes = R.color.briar_orange_500;
showUnlinkWarning = false;
wizardButton.setVisibility(VISIBLE);
} else if (status.getMailboxCompatibility() < 0) {
tintRes = R.color.briar_red_500; tintRes = R.color.briar_red_500;
if (status.getMailboxCompatibility() == API_CLIENT_TOO_OLD) { if (status.getMailboxCompatibility() == API_CLIENT_TOO_OLD) {
title = getString(R.string.mailbox_status_app_too_old_title); title = getString(R.string.mailbox_status_app_too_old_title);
@@ -160,18 +172,6 @@ public class MailboxStatusFragment extends Fragment {
iconRes = R.drawable.alerts_and_states_error; iconRes = R.drawable.alerts_and_states_error;
showUnlinkWarning = true; showUnlinkWarning = true;
wizardButton.setVisibility(GONE); wizardButton.setVisibility(GONE);
} else if (status.hasProblem(System.currentTimeMillis())) {
tintRes = R.color.briar_red_500;
title = getString(R.string.mailbox_status_failure_title);
iconRes = R.drawable.alerts_and_states_error;
showUnlinkWarning = false;
wizardButton.setVisibility(VISIBLE);
} else if (status.getAttemptsSinceSuccess() > 0) {
iconRes = R.drawable.ic_help_outline_white;
title = getString(R.string.mailbox_status_problem_title);
tintRes = R.color.briar_orange_500;
showUnlinkWarning = false;
wizardButton.setVisibility(VISIBLE);
} else { } else {
iconRes = R.drawable.ic_check_circle_outline; iconRes = R.drawable.ic_check_circle_outline;
title = getString(R.string.mailbox_status_connected_title); title = getString(R.string.mailbox_status_connected_title);

View File

@@ -33,7 +33,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/current_password" android:hint="@string/current_password"
android:imeOptions="flagNoPersonalizedLearning"
android:importantForAutofill="no" android:importantForAutofill="no"
android:inputType="textPassword" android:inputType="textPassword"
android:maxLines="1" /> android:maxLines="1" />
@@ -58,7 +57,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/choose_new_password" android:hint="@string/choose_new_password"
android:imeOptions="flagNoPersonalizedLearning"
android:importantForAutofill="no" android:importantForAutofill="no"
android:inputType="textPassword" android:inputType="textPassword"
android:maxLines="1" /> android:maxLines="1" />
@@ -80,7 +78,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/confirm_new_password" android:hint="@string/confirm_new_password"
android:imeOptions="flagNoPersonalizedLearning|actionDone" android:imeOptions="actionDone"
android:importantForAutofill="no" android:importantForAutofill="no"
android:inputType="textPassword" android:inputType="textPassword"
android:maxLines="1" /> android:maxLines="1" />

View File

@@ -19,7 +19,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/choose_forum_hint" android:hint="@string/choose_forum_hint"
android:imeOptions="flagNoPersonalizedLearning"
android:importantForAutofill="no" android:importantForAutofill="no"
android:inputType="text|textCapSentences" android:inputType="text|textCapSentences"
android:maxLines="1" /> android:maxLines="1" />

View File

@@ -25,7 +25,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:imeOptions="flagNoPersonalizedLearning|actionSend" android:imeOptions="actionSend"
android:inputType="textMultiLine|textCapSentences|textAutoCorrect" android:inputType="textMultiLine|textCapSentences|textAutoCorrect"
android:minHeight="@dimen/text_input_height" android:minHeight="@dimen/text_input_height"
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorPrimary"

View File

@@ -30,7 +30,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:hint="@string/set_contact_alias_hint" android:hint="@string/set_contact_alias_hint"
android:imeOptions="flagNoPersonalizedLearning"
android:inputType="text|textCapWords" android:inputType="text|textCapWords"
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/text_size_medium" /> android:textSize="@dimen/text_size_medium" />

View File

@@ -19,7 +19,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/groups_create_group_hint" android:hint="@string/groups_create_group_hint"
android:imeOptions="flagNoPersonalizedLearning"
android:importantForAutofill="no" android:importantForAutofill="no"
android:inputType="text|textCapSentences" android:inputType="text|textCapSentences"
android:maxLines="1" /> android:maxLines="1" />

View File

@@ -205,7 +205,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:hint="@string/contact_link_hint" android:hint="@string/contact_link_hint"
android:imeOptions="flagNoPersonalizedLearning"
android:importantForAutofill="no" android:importantForAutofill="no"
android:inputType="textUri" /> android:inputType="textUri" />

View File

@@ -136,7 +136,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:hint="@string/add_contact_choose_a_nickname" android:hint="@string/add_contact_choose_a_nickname"
android:imeOptions="flagNoPersonalizedLearning"
android:importantForAutofill="no" android:importantForAutofill="no"
android:inputType="text|textCapWords" /> android:inputType="text|textCapWords" />

View File

@@ -27,7 +27,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/enter_password" android:hint="@string/enter_password"
android:imeOptions="flagNoPersonalizedLearning|actionDone" android:imeOptions="actionDone"
android:inputType="textPassword" android:inputType="textPassword"
android:maxLines="1" /> android:maxLines="1" />

View File

@@ -1,43 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_xlarge">
<ProgressBar
android:id="@+id/progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="@dimen/hero_square"
android:layout_height="@dimen/hero_square"
android:indeterminate="true"
app:layout_constraintBottom_toTopOf="@+id/progressMessage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.25"
app:layout_constraintVertical_chainStyle="packed"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/progressMessage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_xlarge"
android:gravity="center"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progress"
tools:text="@string/blogs_rss_feeds_import_progress" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>

View File

@@ -28,7 +28,6 @@
android:id="@+id/user_comment" android:id="@+id/user_comment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:imeOptions="flagNoPersonalizedLearning"
android:inputType="textMultiLine|textCapSentences" android:inputType="textMultiLine|textCapSentences"
tools:hint="@string/describe_crash" /> tools:hint="@string/describe_crash" />
@@ -52,7 +51,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/optional_contact_email" android:hint="@string/optional_contact_email"
android:imeOptions="flagNoPersonalizedLearning"
android:inputType="textEmailAddress" android:inputType="textEmailAddress"
android:maxLines="1" /> android:maxLines="1" />
@@ -63,8 +61,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_large" android:layout_marginLeft="@dimen/margin_large"
android:layout_marginTop="@dimen/margin_large"
android:layout_marginRight="@dimen/margin_large" android:layout_marginRight="@dimen/margin_large"
android:layout_marginTop="@dimen/margin_large"
android:text="@string/privacy_policy" android:text="@string/privacy_policy"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1" android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

View File

@@ -23,7 +23,7 @@
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:gravity="top" android:gravity="top"
android:hint="@string/blogs_rss_feeds_import_hint" android:hint="@string/blogs_rss_feeds_import_hint"
android:imeOptions="flagNoPersonalizedLearning|actionDone" android:imeOptions="actionDone"
android:importantForAutofill="no" android:importantForAutofill="no"
android:inputType="textUri" android:inputType="textUri"
android:padding="@dimen/margin_medium" android:padding="@dimen/margin_medium"

View File

@@ -32,7 +32,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/choose_nickname" android:hint="@string/choose_nickname"
android:imeOptions="flagNoPersonalizedLearning|actionNext" android:imeOptions="actionNext"
android:inputType="text|textCapWords" android:inputType="text|textCapWords"
android:maxLines="1" /> android:maxLines="1" />

View File

@@ -33,7 +33,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/choose_password" android:hint="@string/choose_password"
android:imeOptions="flagNoPersonalizedLearning|actionNext" android:imeOptions="actionNext"
android:inputType="textPassword" android:inputType="textPassword"
android:maxLines="1"> android:maxLines="1">
@@ -71,7 +71,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/confirm_password" android:hint="@string/confirm_password"
android:imeOptions="flagNoPersonalizedLearning|actionNext" android:imeOptions="actionNext"
android:inputType="textPassword" android:inputType="textPassword"
android:maxLines="1" /> android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_import_file"
android:icon="@drawable/ic_add_white"
android:title="@string/blogs_rss_feeds_import_title"
app:showAsAction="never"/>
</menu>

View File

@@ -104,7 +104,7 @@
<string name="bt_plugin_status_disabled">Briar е настроен да не използва Bluetooth</string> <string name="bt_plugin_status_disabled">Briar е настроен да не използва Bluetooth</string>
<!--Notifications--> <!--Notifications-->
<string name="reminder_notification_title">Отписани сте от Briar</string> <string name="reminder_notification_title">Отписани сте от Briar</string>
<string name="reminder_notification_text">За да влезете, докоснете</string> <string name="reminder_notification_text">Докоснете за повторно влизане.</string>
<string name="reminder_notification_channel_title">Напомняне за вход в Briar</string> <string name="reminder_notification_channel_title">Напомняне за вход в Briar</string>
<string name="reminder_notification_dismiss">Отказ</string> <string name="reminder_notification_dismiss">Отказ</string>
<string name="ongoing_notification_title">Вписани в Briar</string> <string name="ongoing_notification_title">Вписани в Briar</string>
@@ -232,12 +232,9 @@
<string name="exchanging_contact_details">Обмяна на данни за контакт\u2026</string> <string name="exchanging_contact_details">Обмяна на данни за контакт\u2026</string>
<string name="contact_added_toast">Добавен контакт: %s</string> <string name="contact_added_toast">Добавен контакт: %s</string>
<string name="contact_already_exists">Контактът %s вече съществува</string> <string name="contact_already_exists">Контактът %s вече съществува</string>
<string name="contact_already_exists_general">Контактът вече съществува</string>
<string name="qr_code_invalid">Кодът за QR е недействителен</string> <string name="qr_code_invalid">Кодът за QR е недействителен</string>
<string name="qr_code_too_old_1">Сканираният код за QR е от по-ранно издание на Briar.\n\nНека вашия контакт инсталира последното издание и да пробва отново.</string> <string name="qr_code_too_old_1">Сканираният код за QR е от по-ранно издание на Briar.\n\nНека вашия контакт инсталира последното издание и да пробва отново.</string>
<string name="qr_code_too_new_1">Сканираният код за QR е от по-ново издание на Briar.\n\nИнсталирайте последното издание и пробвайте отново.</string> <string name="qr_code_too_new_1">Сканираният код за QR е от по-ново издание на Briar.\n\nИнсталирайте последното издание и пробвайте отново.</string>
<string name="mailbox_qr_code_for_contact">Сканираният код за QR е от Briar Пощенска кутия.\n\nАко искате да свържете Пощенска кутия използвайте Настройки &gt; Пощенска кутия от менюто.</string>
<string name="qr_code_format_unknown">Сканираният код за QR не предназначен за добавяне на контакт в Briar.\n\nЗа тази цел използвайте кода, на екрана на контакта ви.</string>
<string name="camera_error">Грешка в камерата</string> <string name="camera_error">Грешка в камерата</string>
<string name="connecting_to_device">Свързване с устройство\u2026</string> <string name="connecting_to_device">Свързване с устройство\u2026</string>
<string name="authenticating_with_device">Удостоверяване с устройство\u2026</string> <string name="authenticating_with_device">Удостоверяване с устройство\u2026</string>
@@ -432,10 +429,6 @@
<string name="forum_declined_toast">Поканата е отказана</string> <string name="forum_declined_toast">Поканата е отказана</string>
<string name="shared_by_format">Споделен от %s</string> <string name="shared_by_format">Споделен от %s</string>
<string name="forum_invitation_already_sharing">Вече е споделен</string> <string name="forum_invitation_already_sharing">Вече е споделен</string>
<string name="forum_invitation_already_invited">Поканата вече е изпратена</string>
<string name="forum_invitation_invite_received">Поканата вече е получена</string>
<string name="forum_invitation_not_supported">Не се поддържа от този контакт</string>
<string name="forum_invitation_error">Грешка. Това е дефект и не е причинено от вас</string>
<string name="forum_invitation_response_accepted_sent">Приехте поканата от %s за членство във форум.</string> <string name="forum_invitation_response_accepted_sent">Приехте поканата от %s за членство във форум.</string>
<string name="forum_invitation_response_declined_sent">Отказахте поканата на %s за членство във форум.</string> <string name="forum_invitation_response_declined_sent">Отказахте поканата на %s за членство във форум.</string>
<string name="forum_invitation_response_declined_auto">Поканата от %s за членство във форум е отказана автоматично.</string> <string name="forum_invitation_response_declined_auto">Поканата от %s за членство във форум е отказана автоматично.</string>
@@ -486,9 +479,8 @@
<string name="blogs_rss_feeds_import">Внасяне на емисия на RSS</string> <string name="blogs_rss_feeds_import">Внасяне на емисия на RSS</string>
<string name="blogs_rss_feeds_import_button">Внасяне</string> <string name="blogs_rss_feeds_import_button">Внасяне</string>
<string name="blogs_rss_feeds_import_hint">рес на емисия</string> <string name="blogs_rss_feeds_import_hint">рес на емисия</string>
<string name="blogs_rss_feeds_import_progress">Внасяне на емисия на RSS</string>
<string name="blogs_rss_feeds_import_error">Грешка при внасяне на емисията.</string> <string name="blogs_rss_feeds_import_error">Грешка при внасяне на емисията.</string>
<string name="blogs_rss_feeds_import_title">Внасяне на емисия от файл</string> <string name="blogs_rss_feeds_import_exists">Емисията вече е внесена.</string>
<string name="blogs_rss_feeds">Емисии на RSS</string> <string name="blogs_rss_feeds">Емисии на RSS</string>
<string name="blogs_rss_feeds_manage_imported">Внесена:</string> <string name="blogs_rss_feeds_manage_imported">Внесена:</string>
<string name="blogs_rss_feeds_manage_author">Автор:</string> <string name="blogs_rss_feeds_manage_author">Автор:</string>
@@ -599,9 +591,7 @@
<string name="mailbox_setup_download_link">Споделяне на препратка за изтегляне</string> <string name="mailbox_setup_download_link">Споделяне на препратка за изтегляне</string>
<string name="mailbox_setup_button_scan">Сканиране на кода за QR на пощенска кутия</string> <string name="mailbox_setup_button_scan">Сканиране на кода за QR на пощенска кутия</string>
<string name="permission_camera_qr_denied_body">Отказахте достъп до камерата, но достъп е необходим за сканиране на кодове за QR.\n\nОбмислете дали да не дадете разрешение.</string> <string name="permission_camera_qr_denied_body">Отказахте достъп до камерата, но достъп е необходим за сканиране на кодове за QR.\n\nОбмислете дали да не дадете разрешение.</string>
<string name="mailbox_setup_connecting">Свързване с Пощенска кутия…</string>
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".--> <!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
<string name="mailbox_setup_connecting_info">Може да отнеме %1s</string>
<string name="mailbox_setup_already_paired_title">Пощенската кутия е вече свързана</string> <string name="mailbox_setup_already_paired_title">Пощенската кутия е вече свързана</string>
<string name="mailbox_setup_already_paired_description">Прекъснете връзката с пощенската кутия от другото устройство и опитайте отново.</string> <string name="mailbox_setup_already_paired_description">Прекъснете връзката с пощенската кутия от другото устройство и опитайте отново.</string>
<string name="mailbox_setup_io_error_title">Грешка при свързване</string> <string name="mailbox_setup_io_error_title">Грешка при свързване</string>

View File

@@ -6,7 +6,7 @@
<string name="setup_next">Següent</string> <string name="setup_next">Següent</string>
<string name="setup_password_intro">Establiu una contrasenya</string> <string name="setup_password_intro">Establiu una contrasenya</string>
<string name="setup_password_explanation">El compte de Briar s\'emmagatzema xifrat en el vostre dispositiu, no en el núvol. Si oblideu la contrasenya o desinstal·leu Briar no podreu recuperar el vostre compte ni les dades associades.\n\nTrieu una contrasenya llarga que sigui difícil d\'endevinar, com ara quatre paraules aleatòries o deu lletres, números i símbols aleatoris.</string> <string name="setup_password_explanation">El compte de Briar s\'emmagatzema xifrat en el vostre dispositiu, no en el núvol. Si oblideu la contrasenya o desinstal·leu Briar no podreu recuperar el vostre compte ni les dades associades.\n\nTrieu una contrasenya llarga que sigui difícil d\'endevinar, com ara quatre paraules aleatòries o deu lletres, números i símbols aleatoris.</string>
<string name="dnkm_doze_intro">Per rebre missatges, Briar necessita estar connectat en segon pla.</string> <string name="dnkm_doze_intro">Per rebre missatges Briar necessita estar connectat en segon pla.</string>
<string name="dnkm_doze_explanation">Per rebre missatges Briar necessita estar connectat en segon pla. Desactiveu les optimitzacions de la bateria per permetre que Briar resti sempre connectat.</string> <string name="dnkm_doze_explanation">Per rebre missatges Briar necessita estar connectat en segon pla. Desactiveu les optimitzacions de la bateria per permetre que Briar resti sempre connectat.</string>
<string name="choose_nickname">Trieu el sobrenom</string> <string name="choose_nickname">Trieu el sobrenom</string>
<string name="choose_password">Trieu la contrasenya</string> <string name="choose_password">Trieu la contrasenya</string>
@@ -19,10 +19,10 @@
<string name="don_t_ask_again">No tornis a preguntar-ho</string> <string name="don_t_ask_again">No tornis a preguntar-ho</string>
<string name="dnkm_huawei_protected_text">Feu un toc sobre el botó següent i assegureu-vos de que Briar consta com a protegit a la pantalla «Aplicacions protegides».</string> <string name="dnkm_huawei_protected_text">Feu un toc sobre el botó següent i assegureu-vos de que Briar consta com a protegit a la pantalla «Aplicacions protegides».</string>
<string name="dnkm_huawei_protected_button">Protegeix Briar</string> <string name="dnkm_huawei_protected_button">Protegeix Briar</string>
<string name="dnkm_huawei_protected_help">Si no afegeixes Briar a la llista d\'aplicacions protegides, no podrà executar-se en segon pla.</string> <string name="dnkm_huawei_protected_help">Si no afegiu Briar a la llista d\'aplicacions protegides, s\'evitarà que Briar s\'executi en segon pla.</string>
<string name="dnkm_huawei_app_launch_text">Premeu el botó, obriu la pantalla «Llença app» i assegureu-vos que Briar està configurat com «Gestiona a ma».</string> <string name="dnkm_huawei_app_launch_text">Premeu el botó, obriu la pantalla «Llença app» i assegureu-vos que Briar està configurat com «Gestiona a ma».</string>
<string name="dnkm_huawei_app_launch_help">Si Briar no està configurat com a «Gestiona manualment» a la pantalla «Llença app», no podrà executar-se en segon pla.</string> <string name="dnkm_huawei_app_launch_help">Si Briar no està configurat com a «Gestiona manualment» a la pantalla «Llença app», no podrà executar-se en segon pla.</string>
<string name="dnkm_xiaomi_text">Per executar-se en segon pla, Briar necessita ser fixat en la llista d\'aplicacions recents.</string> <string name="dnkm_xiaomi_text">Per executar-se en segon pla, Briar necessita ser blocat en la llista d\'aplicacions recents.</string>
<string name="dnkm_xiaomi_button">Protegeix Briar</string> <string name="dnkm_xiaomi_button">Protegeix Briar</string>
<string name="dnkm_xiaomi_help">Si Briar no està blocat a la llista d\'aplicacions recents, no podrà executar-se en segon pla.</string> <string name="dnkm_xiaomi_help">Si Briar no està blocat a la llista d\'aplicacions recents, no podrà executar-se en segon pla.</string>
<string name="dnkm_xiaomi_dialog_body_old">1. Obriu la llista d\'aplicacions recents (de canvi d\'aplicació)\n\n2. Desplaceu avall la icona de Briar per mostrar la icona del cadenat\n\n3. Si el cadenat és obert, premeu per tancar-lo.</string> <string name="dnkm_xiaomi_dialog_body_old">1. Obriu la llista d\'aplicacions recents (de canvi d\'aplicació)\n\n2. Desplaceu avall la icona de Briar per mostrar la icona del cadenat\n\n3. Si el cadenat és obert, premeu per tancar-lo.</string>
@@ -235,7 +235,6 @@ Així que l\'actualitzi li veureu una icona diferent .</string>
<string name="exchanging_contact_details">Intercanviant els detalls del contacte\u2026</string> <string name="exchanging_contact_details">Intercanviant els detalls del contacte\u2026</string>
<string name="contact_added_toast">S\'ha afegit el contacte %s</string> <string name="contact_added_toast">S\'ha afegit el contacte %s</string>
<string name="contact_already_exists">El contacte %s ja existia</string> <string name="contact_already_exists">El contacte %s ja existia</string>
<string name="contact_already_exists_general">El contacte ja existeix</string>
<string name="qr_code_invalid">El codi QR és invàlid</string> <string name="qr_code_invalid">El codi QR és invàlid</string>
<string name="qr_code_too_old_1">El codi QR que heu escanejat prové d\'una versió anterior del Briar.\n\nDemaneu al vostre contacte que actualitzi a la versió més recent i, a continuació, torneu-ho a provar.</string> <string name="qr_code_too_old_1">El codi QR que heu escanejat prové d\'una versió anterior del Briar.\n\nDemaneu al vostre contacte que actualitzi a la versió més recent i, a continuació, torneu-ho a provar.</string>
<string name="qr_code_too_new_1">El codi QR que heu escanejat prové d\'una versió més recent del Briar.\n\nActualitzeu a la darrera versió i torneu-ho a provar.</string> <string name="qr_code_too_new_1">El codi QR que heu escanejat prové d\'una versió més recent del Briar.\n\nActualitzeu a la darrera versió i torneu-ho a provar.</string>
@@ -489,9 +488,8 @@ Així que l\'actualitzi li veureu una icona diferent .</string>
<string name="blogs_rss_feeds_import">Subscriure\'s al canal de notícies RSS</string> <string name="blogs_rss_feeds_import">Subscriure\'s al canal de notícies RSS</string>
<string name="blogs_rss_feeds_import_button">Subscriu-me</string> <string name="blogs_rss_feeds_import_button">Subscriu-me</string>
<string name="blogs_rss_feeds_import_hint">Escriviu l\'URL del canal de notícies RSS</string> <string name="blogs_rss_feeds_import_hint">Escriviu l\'URL del canal de notícies RSS</string>
<string name="blogs_rss_feeds_import_progress">Important fil d\'actualitat RSS...</string>
<string name="blogs_rss_feeds_import_error">Ens sap greu! S\'ha produït un error en subscriure-us al vostre canal de notícies.</string> <string name="blogs_rss_feeds_import_error">Ens sap greu! S\'ha produït un error en subscriure-us al vostre canal de notícies.</string>
<string name="blogs_rss_feeds_import_title">Importa fil d\'actualitat des d\'un fitxer</string> <string name="blogs_rss_feeds_import_exists">Aquest canal ja s\'ha importat.</string>
<string name="blogs_rss_feeds">Canals RSS</string> <string name="blogs_rss_feeds">Canals RSS</string>
<string name="blogs_rss_feeds_manage_imported">Importat:</string> <string name="blogs_rss_feeds_manage_imported">Importat:</string>
<string name="blogs_rss_feeds_manage_author">Autor:</string> <string name="blogs_rss_feeds_manage_author">Autor:</string>

View File

@@ -1,72 +1,55 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources>
<!--Setup--> <!--Setup-->
<string name="setup_title">Vítejte v aplikaci Briar</string> <string name="setup_title">Vítejte v Briar</string>
<string name="setup_name_explanation">Vaše uživatelské jméno bude zobrazeno u jakéhokoli obsahu, který zveřejníte. Následná změna již nebude možná.</string> <string name="setup_name_explanation">Vaše uživatelské jméno bude zobrazeno u jakéhokoli obsahu, který zveřejníte. Následná změna již nebude možná.</string>
<string name="setup_next">Další</string> <string name="setup_next">Další</string>
<string name="setup_password_intro">Zvolte heslo</string> <string name="setup_password_intro">Zvolte heslo</string>
<string name="setup_password_explanation">Váš Briar účet je šifrován a uložen ve vašem zařízení, nikoli v cloudu. Pokud zapomenete své heslo nebo odinstalujete Briar, obnovit Váš účet již nebude možné.\n\nZvolte si dlouhé heslo, které je těžké uhádnout, například čtyři náhodné fráze nebo deset náhodných písmen, čísel a znaků.</string> <string name="setup_password_explanation">Váš Briar účet je šifrován a uložen ve vašem zařízení, nikoli v cloudu. Pokud zapomenete své heslo nebo odinstalujete Briar, obnovit Váš účet již nebude možné.\n\nZvolte si dlouhé heslo, které je těžké uhádnout, například čtyři náhodné fráze nebo deset náhodných písmen, čísel a symbolů.</string>
<string name="dnkm_doze_intro">Pro příjem zpráv je nutné, aby byl Briar stále spuštěn na pozadí.</string> <string name="dnkm_doze_title">Připojení na pozadí</string>
<string name="dnkm_doze_explanation">Pro příjem zpráv je nutné, aby byl Briar spuštěn na pozadí. Vypněte prosím optimalizaci baterie, aby mohl být Briar stále připojen.</string> <string name="dnkm_doze_intro">Pro příjem zpráv je nutné, aby byl Briar stále spuštěn na pozadí.</string>
<string name="choose_nickname">Zvolte si uživatelské jméno</string> <string name="dnkm_doze_explanation">Pro příjem zpráv je nutné, aby byl Briar spuštěn na pozadí. Prosím, vypněte optimalizaci baterie, jedině tak bude Briar stále připojen.</string>
<string name="choose_password">Zvolte si heslo</string> <string name="dnkm_doze_button">Povolit připojení</string>
<string name="confirm_password">Potvrďte své heslo</string> <string name="choose_nickname">Zvolte si uživatelské jméno</string>
<string name="name_too_long">Jméno je příliš dlouhé</string> <string name="choose_password">Zvolte si heslo</string>
<string name="password_too_weak">Heslo je příliš slabé</string> <string name="confirm_password">Potvrďte své heslo</string>
<string name="passwords_do_not_match">Zadaná hesla se neshodují</string> <string name="name_too_long">Jméno je příliš dlouhé</string>
<string name="create_account_button">Vytvořit účet</string> <string name="password_too_weak">Heslo je příliš slabé</string>
<string name="more_info">Další informace</string> <string name="passwords_do_not_match">Zadaná hesla se neshodují</string>
<string name="don_t_ask_again">Znovu se neptat</string> <string name="create_account_button">Vytvořit účet</string>
<string name="dnkm_huawei_protected_text">Klepněte na tlačítko níže a ujistěte se, že byl Briar zařazen mezi „Chráněné aplikace“.</string> <string name="more_info">Další informace</string>
<string name="dnkm_huawei_protected_button">Chránit Briar</string> <string name="don_t_ask_again">Znovu se již neptat</string>
<string name="dnkm_huawei_protected_help">Pokud nebyl Briar přidán mezi chráněné aplikace, nebude ho možné spustit na pozadí.</string> <string name="dnkm_huawei_protected_text">Klikněte na níže uvedené tlačítko a ujistěte se, že byl Briar zařazen mezi \"Chráněné aplikace\".</string>
<string name="dnkm_huawei_app_launch_text">Klepněte na tlačítko níže, otevřete nabídku „Spouštění aplikací“ a ujistěte se, že je Briar nastaven na „Ruční správa“.</string> <string name="dnkm_huawei_protected_button">Chránit Briar</string>
<string name="dnkm_huawei_app_launch_help">Pokud Briar není na obrazovce „Spouštění aplikací“ nastaven na „Ruční správa“, nebude moci běžet na pozadí.</string> <string name="dnkm_huawei_protected_help">Pokud nebyl Briar přidán mezi chráněné aplikace, nebude ho možné spustit na pozadí.</string>
<string name="dnkm_xiaomi_text">Aby mohl Briar běžet na pozadí, musí být uzamčen v seznamu nedávných aplikací.</string> <string name="dnkm_warning_dozed">%s nebylo možné spustit na pozadí</string>
<string name="dnkm_xiaomi_button">Chránit Briar</string> <!--Login-->
<string name="dnkm_xiaomi_help">Pokud není Briar uzamčen v seznamu nedávných aplikací, nebude moci běžet na pozadí.</string> <string name="enter_password">Heslo</string>
<string name="dnkm_xiaomi_dialog_body_old">1. Otevřete seznam nedávných aplikací (také známý jako přepínač aplikací)\n\n2. Přejeďte prstem dolů po obrazu Briaru pro zobrazení ikony zámku\n\n3. Pokud není zámek uzamčen, uzamkněte ho klepnutím na něj</string> <string name="try_again">Zadali jste špatné heslo, zkuste to znovu</string>
<string name="dnkm_xiaomi_dialog_body_new">1. Otevřete seznam nedávných aplikací (také známý jako přepínač aplikací)\n\n2. Pokud má Briar vedle svého názvu malý obrázek zámku, nemusíte nic dělat\n\n3. Pokud tam žádný zámek není, stiskněte a podržte obraz Briaru, dokud se nezobrazí tlačítko visacího zámku, a pak na něj klepněte</string> <string name="sign_in_button">Přihlásit se</string>
<string name="dnkm_xiaomi_lock_apps_text">Klepněte na tlačítko níže pro otevření nastavení zabezpečení. Klepněte na „Zvýšení rychlosti“, poté na „Uzamčení aplikací“ a ujistěte se, že je Briar nastaven na „Uzamčeno“.</string> <string name="forgotten_password">Nepamatuji si své heslo</string>
<string name="dnkm_xiaomi_lock_apps_help">Pokud není Briar na obrazovce „Uzamknutí aplikací“ nastaven na „Uzamčeno“, nebude moci běžet na pozadí.</string> <string name="dialog_title_lost_password">Ztracené heslo</string>
<string name="dnkm_warning_dozed_1">Briar nemůže běžet na pozadí</string> <string name="dialog_message_lost_password">Váš Briar účet je šifrován a uložen ve vašem zařízení, nikoli v cloudu, z tohoto důvodu není možné obnovit Vaše heslo. Chcete odstranit svůj účet a začít znovu?\n\nUpozornění: Vaše identita, kontakty a zprávy budou permanentně ztraceny.</string>
<!--Login--> <string name="startup_failed_notification_title">Briar nemohl být spuštěn</string>
<string name="enter_password">Heslo</string> <string name="startup_failed_notification_text">Klikněte pro více informací</string>
<string name="try_again">Zadali jste špatné heslo, zkuste to znovu</string>
<string name="dialog_title_cannot_check_password">Nepodařilo se zkontrolovat heslo</string>
<string name="dialog_message_cannot_check_password">Briar nemůže zkontrolovat vaše heslo. Zkuste tento problém vyřešit restartováním zařízení.</string>
<string name="sign_in_button">Přihlásit se</string>
<string name="forgotten_password">Nepamatuji si své heslo</string>
<string name="dialog_title_lost_password">Ztracené heslo</string>
<string name="dialog_message_lost_password">Váš Briar účet je šifrován a uložen ve vašem zařízení, nikoli v cloudu, z tohoto důvodu není možné obnovit Vaše heslo. Chcete odstranit svůj účet a začít znovu?\n\nUpozornění: Vaše identita, kontakty a zprávy budou permanentně ztraceny.</string>
<string name="startup_failed_activity_title">Spuštění Briar selhalo.</string> <string name="startup_failed_activity_title">Spuštění Briar selhalo.</string>
<string name="startup_failed_clock_error">Nepodařilo se spustit Briar, protože hodiny vašeho zařízení jsou špatně nastavené.\n\nNastavte prosím hodiny vašeho zařízení na správný čas a zkuste to znovu.</string> <string name="startup_failed_db_error">Z nějakého důvodu je vaše databáze Briar poškozena. Váš účet, vaše data a všechny vaše kontakty budou ztraceny. Bohužel musíte přeinstalovat Briar nebo nastavit nový účet výběrem položky \'Zapomněl jsem heslo\' v řádku zadat heslo.</string>
<string name="startup_failed_db_error">Aplikaci Briar se nepodařilo otevřít databázi obsahující váš účet, kontakty a zprávy.\n\nPřejděte na nejnovější verzi aplikace a zkuste to znovu, nebo si nastavte nový účet tak, že na výzvu k zadání hesla zvolíte „Zapomněl jsem heslo.</string> <string name="startup_failed_data_too_old_error">Váš účet byl vytvořen se starou verzí aplikace a nemůže být otevřen v této verzi. Musíte přeinstalovat starou verzi nebo nastavit nový účet vybráním \'Zapomněl jsem své heslo v nabídce hesla.</string>
<string name="startup_failed_data_too_old_error">Váš účet byl vytvořen ve starší verzi této aplikace a v této verzi jej nelze otevřít.\n\nMusíte buď přeinstalovat starou verzi, nebo nastavit nový účet tak, že na výzvu k zadání hesla vyberete možnost „Zapomněl jsem heslo“.</string> <string name="startup_failed_data_too_new_error">Tato verze aplikace je zastaralá. Prosím aktualizujte na nejvyšší verzi a zkuste to znovu.</string>
<string name="startup_failed_data_too_new_error">Váš účet byl vytvořen s novější verzí této aplikace a s touto verzí jej nelze otevřít.\n\nPřejděte prosím na nejnovější verzi a zkuste to znovu.</string> <string name="startup_failed_service_error">Briar nemohl spustit vyžadovaný plugin. Tento problém vyřeší přeinstalování Briar. Mějte prosím na vědomí, že přeinstalováním ztratíte veškerá data pro váš účet, protože Briar nepoužívá centralizované ukládání vašich dat na serverech.</string>
<string name="startup_failed_service_error">Aplikaci Briar se nepodařilo spustit požadovanou komponentu.\n\nAktualizujte prosím aplikaci na nejnovější verzi a zkuste to znovu.</string>
<plurals name="expiry_warning"> <plurals name="expiry_warning">
<item quantity="one">Toto je testovací verze Briar. Váš účet a jeho platnost vyprší po %d dnech a není možné ho obnovit.</item> <item quantity="one">Toto je testovací verze Briar. Váš účet a jeho platnost vyprší po %d dnech a není možné ho obnovit.</item>
<item quantity="few">Toto je testovací verze Briar. Váš účet a jeho platnost vyprší po %d dnech a není možné ho obnovit.</item> <item quantity="few">Toto je testovací verze Briar. Váš účet a jeho platnost vyprší po %d dnech a není možné ho obnovit.</item>
<item quantity="many">Toto je testovací verze Briar. Váš účet a jeho platnost vyprší po %d dnech a není možné ho obnovit.</item> <item quantity="many">Toto je testovací verze Briar. Váš účet a jeho platnost vyprší po %d dnech a není možné ho obnovit.</item>
<item quantity="other">Toto je testovací verze Briar. Váš účet a jeho platnost vyprší po %d dnech a není možné ho obnovit.</item> <item quantity="other">Toto je testovací verze Briar. Váš účet a jeho platnost vyprší po %d dnech a není možné ho obnovit.</item>
</plurals> </plurals>
<plurals name="old_android_expiry_warning"> <string name="expiry_update">Datum expirace pro testování bylo prodlouženo. Váš účet nyní bude expirovat po %d dnech.</string>
<item quantity="one">Systém Android 4 již není podporován. Briar přestane fungovat %s (za %d den). Nainstalujte si prosím Briar na novější zařízení a vytvořte si nový účet.</item>
<item quantity="few">Systém Android 4 již není podporován. Briar přestane fungovat %s (za %d dny). Nainstalujte si prosím Briar na novější zařízení a vytvořte si nový účet.</item>
<item quantity="many">Systém Android 4 již není podporován. Briar přestane fungovat %s (za %d dní). Nainstalujte si prosím Briar na novější zařízení a vytvořte si nový účet.</item>
<item quantity="other">Systém Android 4 již není podporován. Briar přestane fungovat %s (za %d dní). Nainstalujte si prosím Briar na novější zařízení a vytvořte si nový účet.</item>
</plurals>
<string name="expiry_date_reached">Platnost tohoto software vypršela.\nDěkujeme za jeho otestování!</string> <string name="expiry_date_reached">Platnost tohoto software vypršela.\nDěkujeme za jeho otestování!</string>
<string name="download_briar">Pro pokračování v používání aplikace Briar si prosím stáhněte její nejnovější verzi.</string> <string name="download_briar">Pro pokračování používání Briar, stáhněte si prosím verzi 1.0.</string>
<string name="create_new_account">Budete potřebovat vytvořit nový účet, ale můžete použít stejné uživatelské jméno.</string> <string name="create_new_account">Budete potřebovat vytvořit nový účet, ale můžete použít stejné uživatelské jméno.</string>
<string name="download_briar_button">Stáhnout nejnovější vydání</string> <string name="download_briar_button">Stáhnout Briar 1.0</string>
<string name="old_android_expiry_date_reached">Briar již neběží na systému Android 4.\nNainstalujte prosím Briar na novější zařízení.</string>
<string name="old_android_delete_account">Klepnutím na tlačítko níže odstraníte svůj účet z tohoto zařízení.</string>
<string name="delete_account_button">Odstranit účet</string>
<string name="startup_open_database">Dešifrování databáze...</string> <string name="startup_open_database">Dešifrování databáze...</string>
<string name="startup_migrate_database">Aktualizování databáze...</string> <string name="startup_migrate_database">Aktualizování databáze...</string>
<string name="startup_compact_database">Komprimování databáze…</string>
<!--Navigation Drawer--> <!--Navigation Drawer-->
<string name="nav_drawer_open_description">Otevřít navigační lištu</string> <string name="nav_drawer_open_description">Otevřít navigační lištu</string>
<string name="nav_drawer_close_description">Zavřít navigační lištu</string> <string name="nav_drawer_close_description">Zavřít navigační lištu</string>
@@ -75,44 +58,13 @@
<string name="forums_button">Fóra</string> <string name="forums_button">Fóra</string>
<string name="blogs_button">Blogy</string> <string name="blogs_button">Blogy</string>
<!--This is part of the main menu. The app will be locked when this is tapped.--> <!--This is part of the main menu. The app will be locked when this is tapped.-->
<string name="lock_button">Zamknout aplikaci</string>
<string name="settings_button">Nastavení</string> <string name="settings_button">Nastavení</string>
<string name="sign_out_button">Odhlásit se</string> <string name="sign_out_button">Odhlásit se</string>
<string name="transports_onboarding_text">Klepněte sem pro ovládání způsobu, kterým se Briar připojuje k vašim kontaktům.</string> <!--Transports-->
<!--Transports: Tor-->
<string name="transport_tor">Internet</string> <string name="transport_tor">Internet</string>
<string name="tor_device_status_online_wifi">Váš mobil má přístup k internetu přes Wi-Fi</string>
<string name="tor_device_status_online_mobile">Váš mobil má přístup k internetu přes mobilní data</string>
<string name="tor_device_status_offline">Váš mobil nemá přístup k internetu</string>
<string name="tor_plugin_status_enabling">Briar se připojuje k internetu</string>
<string name="tor_plugin_status_active">Briar je připojen k internetu</string>
<string name="tor_plugin_status_inactive">Briar se nemůže připojit k internetu</string>
<string name="tor_plugin_status_disabled">Briar je nastaven tak, aby nepoužíval internet</string>
<string name="tor_plugin_status_disabled_mobile_data">Briar je nastaven tak, aby nepoužíval mobilní data</string>
<string name="tor_plugin_status_disabled_battery">Briar je nastaven tak, aby nepoužíval internet při provozu na baterii</string>
<string name="tor_plugin_status_disabled_country_blocked">Briar je nastaven tak, aby v této zemi nepoužíval internet</string>
<!--Transports: Wi-Fi-->
<string name="transport_lan">Wi-Fi</string>
<string name="transport_lan_long">Stejná síť Wi-Fi</string>
<string name="lan_device_status_on">Váš mobil je připojen k síti Wi-Fi</string>
<string name="lan_device_status_off">Váš mobil není připojen k síti Wi-Fi</string>
<string name="lan_plugin_status_enabling">Briar se připojuje k síti Wi-Fi</string>
<string name="lan_plugin_status_active">Briar se připojuje k síti Wi-Fi</string>
<string name="lan_plugin_status_inactive">Briar se nemůže připojit k síti Wi-Fi</string>
<string name="lan_plugin_status_disabled">Briar je nastaven tak, aby nepoužíval síť Wi-Fi</string>
<!--Transports: Bluetooth-->
<string name="transport_bt">Bluetooth</string> <string name="transport_bt">Bluetooth</string>
<string name="bt_device_status_on">Bluetooth v mobilu je zapnutý</string> <string name="transport_lan">Wi-Fi</string>
<string name="bt_device_status_off">Bluetooth v mobilu je vypnutý</string>
<string name="bt_plugin_status_enabling">Briar se připojuje k Bluetooth</string>
<string name="bt_plugin_status_active">Briar je připojen k Bluetooth</string>
<string name="bt_plugin_status_inactive">Briar se nemůže připojit k Bluetooth</string>
<string name="bt_plugin_status_disabled">Briar je nastaven tak, aby nepoužíval Bluetooth</string>
<!--Notifications--> <!--Notifications-->
<string name="reminder_notification_title">Byl jste odhlášen z Briar</string>
<string name="reminder_notification_text">Klepněte pro opětovné přihlášení.</string>
<string name="reminder_notification_channel_title">Připomenutí k přihlášení Briar</string>
<string name="reminder_notification_dismiss">Zavřít</string>
<string name="ongoing_notification_title">Přihlásit se do Briar</string> <string name="ongoing_notification_title">Přihlásit se do Briar</string>
<string name="ongoing_notification_text">Kliknutím otevřít Briar</string> <string name="ongoing_notification_text">Kliknutím otevřít Briar</string>
<plurals name="private_message_notification_text"> <plurals name="private_message_notification_text">
@@ -141,110 +93,39 @@
</plurals> </plurals>
<!--Misc--> <!--Misc-->
<string name="now">nyní</string> <string name="now">nyní</string>
<string name="show">Zobrazit</string> <string name="show">Ukázat</string>
<string name="hide">Skrýt</string> <string name="hide">Skrýt</string>
<string name="ok">OK</string> <string name="ok">Ok</string>
<string name="cancel">Zrušit</string> <string name="cancel">Zrušit</string>
<string name="got_it">Chápu</string> <string name="got_it">Chápu</string>
<string name="delete">Odstranit</string> <string name="delete">Odstranit</string>
<string name="accept">Přijmout</string> <string name="accept">Přijmout</string>
<string name="decline">Odmítnout</string> <string name="decline">Odmítnout</string>
<string name="options">Možnosti</string>
<string name="online">Online</string> <string name="online">Online</string>
<string name="offline">Offline</string> <string name="offline">Offline</string>
<string name="send">Odeslat</string> <string name="send">Odeslat</string>
<string name="allow">Povolit</string> <string name="allow">Povolit</string>
<string name="open">Otevřít</string> <string name="open">Otevřít</string>
<string name="change">Změnit</string>
<string name="start">Zapnout</string>
<string name="finish">Dokončit</string>
<string name="no_data">Žádná data</string> <string name="no_data">Žádná data</string>
<string name="ellipsis">...</string> <string name="ellipsis">...</string>
<string name="text_too_long">Zadaný text je příliš dlouhý</string> <string name="text_too_long">Zadaný text je příliš dlouhý</string>
<string name="show_onboarding">Zobrazit nabídku nápovědy</string> <string name="show_onboarding">Zobrazit dialog pro pomoc</string>
<string name="fix">Opravit</string> <string name="fix">Opravit</string>
<string name="help">Pomoc</string> <string name="help">Pomoc</string>
<string name="sorry">Promiňte</string> <string name="sorry">Promiňte</string>
<string name="error_start_activity">Ve vašem systému není dostupné</string>
<string name="status_heading">Stav</string>
<string name="error">Chyba</string>
<string name="info">Informace</string>
<!--Contacts and Private Conversations--> <!--Contacts and Private Conversations-->
<string name="no_contacts">Žádné kontakty k zobrazení</string>
<string name="no_contacts_action">Klepněte na ikonu + pro přidání kontaktu</string>
<string name="date_no_private_messages">Žádné zprávy</string> <string name="date_no_private_messages">Žádné zprávy</string>
<string name="no_private_messages">Žádné zprávy k zobrazení</string> <string name="no_private_messages">Žádné zprávy k zobrazení</string>
<string name="message_hint">Nová zpráva</string> <string name="message_hint">Psát zprávu</string>
<string name="message_hint_auto_delete">Nová mizející zpráva</string>
<string name="message_error">Chyba při odesílání zprávy</string>
<string name="image_caption_hint">Přidat popisek (nepovinné)</string>
<string name="image_attach">Připojit obrázek</string>
<string name="image_attach_error">Nepodařilo se připojit obrázek*ky</string>
<string name="image_attach_error_too_big">Obrázek je příliš velký. Limit je %d MB.</string>
<string name="image_attach_error_invalid_mime_type">Nepodporovaný formát obrázku: %s</string>
<string name="set_contact_alias">Změnit jméno kontaktu</string>
<string name="set_contact_alias_hint">Jméno kontaktu</string>
<string name="menu_item_disappearing_messages">Mizející zprávy</string>
<!--The first placeholder will show a duration like "7 days". The second placeholder at the end will add "Tap to learn more."-->
<string name="auto_delete_msg_you_enabled">Vaše zprávy zmizí za %1$s. %2$s</string>
<!--The placeholder at the end will add "Tap to learn more."-->
<string name="auto_delete_msg_you_disabled">Vaše zprávy nebudou mizet. %1$s</string>
<!--The first placeholder will show a contact's name. The second placeholder will show a duration like "7 days". The third placeholder at the end will add "Tap to learn more."-->
<string name="auto_delete_msg_contact_enabled">Zprávy kontaktu %1$s zmizí za %2$s. %3$s</string>
<plurals name="duration_minutes">
<item quantity="one">%d minutu</item>
<item quantity="few">%d minuty</item>
<item quantity="many">%d minut</item>
<item quantity="other">%d minut</item>
</plurals>
<plurals name="duration_hours">
<item quantity="one">%d hodinu</item>
<item quantity="few">%d hodiny</item>
<item quantity="many">%d hodin</item>
<item quantity="other">%d hodin</item>
</plurals>
<plurals name="duration_days">
<item quantity="one">%d den</item>
<item quantity="few">%d dny</item>
<item quantity="many">%d dní</item>
<item quantity="other">%d dní</item>
</plurals>
<!--The first placeholder will show a contact's name. The second placeholder at the end will add "Tap to learn more."-->
<string name="auto_delete_msg_contact_disabled">Zprávy kontaktu %1$s nebudou mizet. %2$s</string>
<string name="tap_to_learn_more">Klepněte pro více informací.</string>
<string name="auto_delete_changed_warning_title">Mizející zprávy změněny</string>
<string name="auto_delete_changed_warning_message_enabled">Od doby, kdy jste začali psát svou zprávu, byly povoleny mizející zprávy.</string>
<string name="auto_delete_changed_warning_message_disabled">Od doby, kdy jste začali psát svou zprávu, byly povoleny mizející zprávy.</string>
<string name="auto_delete_changed_warning_send">Přesto odeslat</string>
<string name="delete_all_messages">Odstranit všechny zprávy</string>
<string name="dialog_title_delete_all_messages">Potvrdit odstranění zprávy</string>
<string name="dialog_message_delete_all_messages">Opravdu chcete odstranit všechny zprávy?</string>
<string name="dialog_title_not_all_messages_deleted">Nepodařilo se odstranit všechny zprávy</string>
<string name="dialog_message_not_deleted_ongoing_both">Zprávy související s aktuálními pozvánkami a představeními nemohou být smazány dokud nejsou uzavřeny.</string>
<string name="dialog_message_not_deleted_ongoing_introductions">Zprávy související s aktuálními představeními nemohou být smazány dokud nejsou uzavřeny.</string>
<string name="dialog_message_not_deleted_ongoing_invitations">Zprávy související s aktuálními pozvánkami nemohou být smazány dokud nejsou uzavřeny.</string>
<string name="dialog_message_not_deleted_not_all_selected_both">Pro smazání pozvánky nebo představení musíte vybrat žádost a odpověď.</string>
<string name="dialog_message_not_deleted_not_all_selected_introductions">Pro smazání představení musíte vybrat žádost a odpověď.</string>
<string name="dialog_message_not_deleted_not_all_selected_invitations">Pro smazání pozvánky musíte vybrat žádost a odpověď.</string>
<string name="delete_contact">Odstranit kontakt</string> <string name="delete_contact">Odstranit kontakt</string>
<string name="dialog_title_delete_contact">Potvrdit odstranění kontaktu</string> <string name="dialog_title_delete_contact">Potvrdit odstranění kontaktu</string>
<string name="dialog_message_delete_contact">Jste si jisti, že chcete odstranit kontakt a všechny související zprávy s tímto kontaktem?</string> <string name="dialog_message_delete_contact">Jste si jisti, že chcete odstranit kontakt a všechny související zprávy s tímto kontaktem?</string>
<string name="contact_deleted_toast">Kontakt odstraněn</string> <string name="contact_deleted_toast">Kontakt odstraněn</string>
<!--This is shown in the action bar when opening an image in fullscreen that the user sent--> <!--This is shown in the action bar when opening an image in fullscreen that the user sent-->
<string name="you">Vy</string> <string name="you">Vy</string>
<string name="save_image">Uložit obrázek</string>
<string name="dialog_title_save_image">Uložit obrázek?</string>
<string name="dialog_message_save_image">Uložení tohoto obrázku umožní ostatním aplikacím k němu přistupovat.\n\nJste si jisti, že ho chcete uložit?</string>
<string name="save_image_success">Obrázek byl uložen</string>
<string name="save_image_error">Nebylo možné uložit obrázek</string>
<string name="dialog_title_no_image_support">Obrázky jsou nedostupné</string>
<string name="dialog_message_no_image_support">Briar vašich kontaktů ještě nepodporuje obrázkové přílohy. Jakmile navýší na odpovídající verzi aplikace, uvidíte odlišnou ikonu.</string>
<string name="dialog_title_image_support">Nyní můžete tomuto kontaktu posílat obrázky</string>
<string name="dialog_message_image_support">Klepněte na tuto ikonu pro připojení obrázků.</string>
<string name="messaging_too_many_attachments_toast">Pouze prvních %d obrázků bude odesláno</string>
<string name="menu_contact">Kontakt</string>
<!--Adding Contacts--> <!--Adding Contacts-->
<string name="add_contact_title">Přidat kontakt nablízku</string> <string name="add_contact_title">Přidat kontakt</string>
<string name="add_contact_error_two_way">Oskenovali jste vy i druhá strana QR kód toho druhého?</string>
<string name="face_to_face">Musíte se osobně setkat s osobou, kterou si chcete přidat jako kontakt.\n\nToto v budoucnu zabrání komukoli, aby se za vás vydával nebo četl Vaše zprávy.</string> <string name="face_to_face">Musíte se osobně setkat s osobou, kterou si chcete přidat jako kontakt.\n\nToto v budoucnu zabrání komukoli, aby se za vás vydával nebo četl Vaše zprávy.</string>
<string name="continue_button">Pokračovat</string> <string name="continue_button">Pokračovat</string>
<string name="try_again_button">Zkusit znovu</string> <string name="try_again_button">Zkusit znovu</string>
@@ -252,119 +133,37 @@
<string name="exchanging_contact_details">Výměna detailů kontaktu\u2026</string> <string name="exchanging_contact_details">Výměna detailů kontaktu\u2026</string>
<string name="contact_added_toast">Kontakt byl přidán: %s</string> <string name="contact_added_toast">Kontakt byl přidán: %s</string>
<string name="contact_already_exists">Kontakt %s již existuje</string> <string name="contact_already_exists">Kontakt %s již existuje</string>
<string name="contact_already_exists_general">Kontakt již existuje</string>
<string name="qr_code_invalid">QR kód je neplatný</string> <string name="qr_code_invalid">QR kód je neplatný</string>
<string name="qr_code_too_old_1">QR kód, který jste oskenovali pochází ze starší verze Briaru.\n\nProsím požádejte svůj kontakt, aby aktualizoval aplikaci na nejnovější verzi a zkuste to znovu.</string>
<string name="qr_code_too_new_1">QR kód, který jste oskenovali pochází z novější verze Briaru.\n\nProsím aktualizujte Briar na nejnovější verzi a zkuste to znovu.</string>
<string name="mailbox_qr_code_for_contact">QR kód, který jste oskenovali pochází z Briar Mailbox.\n\nPokud chcete odkázat Mailbox, vyberte Nastavení &gt; Mailbox z nabídky Briar.</string>
<string name="qr_code_format_unknown">QR kód, který jste oskenovali není určen pro přidávání Briar kontaktu.\n\nProsím oskenujte QR kód, který je zobrazen na obrazovce vašeho kontaktu.</string>
<string name="camera_error">Vyskytla se chyba fotoaparátu</string> <string name="camera_error">Vyskytla se chyba fotoaparátu</string>
<string name="connecting_to_device">Připojování k zařízení\u2026</string> <string name="connecting_to_device">Připojování k zařízení\u2026</string>
<string name="authenticating_with_device">Ověřování se zařízením\u2026</string> <string name="authenticating_with_device">Ověřování se zařízením\u2026</string>
<string name="connection_error_title">Nebylo možné se připojit k vašemu kontaktu</string>
<string name="connection_error_feedback">Pokud tento problém přetrvává, prosím <a href="feedback">odešlete zpětnou vazbu</a> abyste nám pomohli vylepšit aplikaci.</string>
<string name="info_both_must_scan">Vy i kontakt musíte oskenovat QR kód toho druhého</string>
<!--Adding Contacts Remotely-->
<string name="add_contact_remotely_title_case">Přidat kontakt vzdáleně</string>
<string name="add_contact_nearby_title">Přidat kontakt blízko</string>
<string name="add_contact_remotely_title">Přidat kontakt vzdáleně</string>
<string name="contact_link_intro">Sem vložte odkaz od vašeho kontaktu</string>
<string name="contact_link_hint">Odkaz kontaktu</string>
<string name="paste_button">Vložit</string>
<string name="add_contact_button">Přidat kontakt</string>
<string name="copy_button">Kopírovat</string>
<string name="share_button">Sdílet</string>
<string name="send_link_title">Vyměnit odkazy</string>
<string name="add_contact_choose_nickname">Vybrat přezdívku</string>
<string name="add_contact_choose_a_nickname">Vložit přezdívku</string>
<string name="nickname_intro">Dejte vašemu kontaktu přezdívku. Jen vy ji uvidíte.</string>
<string name="your_link">Dejte tento odkaz kontaktu, který chcete přidat</string>
<string name="link_clip_label">Briar link</string>
<string name="link_copied_toast">Odkaz zkopírován</string>
<string name="adding_contact_error">Došlo k chybě přidávání kontaktu.</string>
<string name="pending_contact_requests_snackbar">Existují čekající žádosti o kontakt</string>
<string name="pending_contact_requests">Čekající žádosti o kontakt</string>
<string name="no_pending_contacts">Žádné čekající kontakty</string>
<string name="waiting_for_contact_to_come_online">Čekání až kontakt bude online...</string>
<string name="connecting">Spojuji...</string>
<string name="adding_contact">Přidávání kontaktu...</string>
<string name="adding_contact_failed">Přidávání kontaktu selhalo</string>
<string name="dialog_title_remove_pending_contact">Potvrdit odebrání</string>
<string name="dialog_message_remove_pending_contact">Tento kontakt je stále přidáván. Pokud ho teď odeberete, nebude přidán.</string>
<string name="own_link_error">Zadejte odkaz vašeho kontaktu, ne svůj.</string>
<string name="nickname_missing">Prosím zadejte přezdívku</string>
<string name="invalid_link">Neplatný odkaz</string>
<string name="unsupported_link">Tento odkaz pochází z novější verze Briaru. Prosím proveďte aktualizaci na nejnovější verzi a zkuste to znovu.</string>
<string name="intent_own_link">Otevřeli jste váš odkaz. Použijte odkaz kontaktu, který chcete přidat.</string>
<string name="missing_link">Prosím zadejte odkaz</string>
<!--This is a numeral indicating the first step in a series of screens-->
<string name="step_1">1</string>
<!--This is a numeral indicating the second step in a series of screens-->
<string name="step_2">2</string>
<plurals name="contact_added_notification_text">
<item quantity="one">Nový kontakt přidán.</item>
<item quantity="few">%d nové kontakty přidány.</item>
<item quantity="many">%d nových kontaktů přidáno.</item>
<item quantity="other">%d nových kontaktů přidáno.</item>
</plurals>
<string name="offline_state">Žádné internetové připojení</string>
<string name="duplicate_link_dialog_title">Duplicitní odkaz</string>
<string name="duplicate_link_dialog_text_1">Již máte čekající kontakt s tímto odkazem: %s</string>
<string name="duplicate_link_dialog_text_1_contact">Již máte kontakt s tímto odkazem: %s</string>
<!--This is a question asking whether two nicknames refer to the same person-->
<string name="duplicate_link_dialog_text_2">Je %1$s a %2$s stejná osoba?</string>
<!--This is a button for answering that two nicknames do indeed refer to the same person. This
string will be used in a dialog button, so if the translation of this string is longer than 20
characters, please use "Yes" instead, and use "No" for the "Different Person" button-->
<string name="same_person_button">Stejná osoba</string>
<!--This is a button for answering that two nicknames refer to different people. This string
will be used in a dialog button, so if the translation of this string longer than 20 characters,
please use "No" instead, and use "Yes" for the "Same Person" button-->
<string name="different_person_button">Jiná osoba</string>
<string name="duplicate_link_dialog_text_3">%1$s a %2$s vám poslali stejný odkaz.\n\nJeden z nich se možná snaží zjistit kdo jsou vaše kontakty.\n\nNeříkejte jim, že jste dostali stejný odkaz od někoho jiného.</string>
<string name="pending_contact_updated_toast">Čekající kontakt aktualizován</string>
<string name="info_both_must_enter_links">Oba kontakty musí přidat odkaz toho druhého</string>
<!--Peer trust levels-->
<string name="peer_trust_level_unverified">Neověřený kontakt</string>
<string name="peer_trust_level_verified">Ověřený kontakt</string>
<string name="peer_trust_level_ourselves"></string>
<string name="peer_trust_level_stranger">Neznámý</string>
<!--Introductions--> <!--Introductions-->
<string name="introduction_onboarding_title">Uvést vaše kontakty</string> <string name="introduction_onboarding_title">Uvést vaše kontakty</string>
<string name="introduction_onboarding_text">Představte vzájemně vaše kontakty, aby se spolu mohli spojit.</string> <string name="introduction_onboarding_text">Můžete si navzájem představit své kontakty, takže se následně nemusejí setkat osobně, aby se připojili k Briar.</string>
<string name="introduction_menu_item">Vytvořit představe</string> <string name="introduction_menu_item">Vytvořit pozvá</string>
<string name="introduction_activity_title">Vybrat kontakt</string> <string name="introduction_activity_title">Vybrat kontakt</string>
<string name="introduction_not_possible">Již máte jedno představení v běhu s těmito kontakty. Prosím nejprve nechte toto dokončit. Pokud vy nebo vaše kontakty nejste často online, může to nějakou dobu trvat.</string>
<string name="introduction_message_title">Pozvat kontakty</string> <string name="introduction_message_title">Pozvat kontakty</string>
<string name="introduction_message_hint">Přidat zprávu (volitelné)</string> <string name="introduction_message_hint">Přidat zprávu (volitelné)</string>
<string name="introduction_button">Vytvořit představe</string> <string name="introduction_button">Vytvořit pozvá</string>
<string name="introduction_sent">Vaše představení bylo odesláno.</string> <string name="introduction_sent">Vaše pozvání bylo odesláno.</string>
<string name="introduction_error">Vyskytla se chyba při tvorbě představení.</string> <string name="introduction_error">Vyskytla se chyba při tvorbě pozvání.</string>
<string name="introduction_response_error">Chyba při odpovědi na pozvání.</string>
<string name="introduction_request_sent">Požádali jste o pozvání %1$s do %2$s.</string> <string name="introduction_request_sent">Požádali jste o pozvání %1$s do %2$s.</string>
<string name="introduction_request_received">%1$s vás požádal o uvedení do %2$s. Chcete přidat %2$s mezi vaše kontakty?</string> <string name="introduction_request_received">%1$s vás požádal o uvedení do %2$s. Chcete přidat %2$s mezi vaše kontakty?</string>
<string name="introduction_request_exists_received">%1$s vás požádal o představení s %2$s, ale %2$s je již ve vašich kontaktech. Pravděpodobně to %1$s neví, ale stále můžete odpovědět:</string> <string name="introduction_request_exists_received">%1$s vás požádal o představení s %2$s, ale %2$s je již ve vašich kontaktech. Pravděpodobně to %1$s neví, ale stále můžete odpovědět:</string>
<string name="introduction_request_answered_received">%1$s vás žádá o pozvání do %2$s.</string> <string name="introduction_request_answered_received">%1$s vás žádá o pozvání do %2$s.</string>
<string name="introduction_response_accepted_sent">Přijali jste představení do %1$s.</string> <string name="introduction_response_accepted_sent">Přijali jste pozvání do %1$s.</string>
<string name="introduction_response_accepted_sent_info">Před tím, než bude přidán %1$s do kontaktů, musí souhlasit s představením. Toto může nějakou dobu trvat.</string>
<string name="introduction_response_declined_sent">Odmítli jste představení do %1$s.</string> <string name="introduction_response_declined_sent">Odmítli jste představení do %1$s.</string>
<string name="introduction_response_declined_auto">Představení %1$s bylo automaticky zamítnuto.</string> <string name="introduction_response_accepted_received">%1$s přijal pozvání do %2$s.</string>
<string name="introduction_response_accepted_received">%1$s přijal představení do %2$s.</string> <string name="introduction_response_declined_received">%1$s odmítl pozvání do %2$s.</string>
<string name="introduction_response_declined_received">%1$s odmítl představení do %2$s.</string> <string name="introduction_response_declined_received_by_introducee">%1$s řekl, že %2$s odmítl pozvání.</string>
<string name="introduction_response_declined_received_by_introducee">%1$s řekl, že %2$s odmítl představení.</string> <plurals name="contact_added_notification_text">
<!--Connect via Bluetooth--> <item quantity="one">Nový kontakt byl přidán.</item>
<string name="menu_item_connect_via_bluetooth">Spojení přes Bluetooth</string> <item quantity="few">Bylo přidáno %d nových kontaktů.</item>
<string name="connect_via_bluetooth_title">Spojení přes Bluetooth</string> <item quantity="many">%d nových kontaktů bylo přidáno.</item>
<string name="connect_via_bluetooth_intro">V případě, že Bluetooth připojení nefunguje automaticky, můžete použít tuto obrazovku pro ruční připojení.\n\nVáš kontakt musí být poblíž, aby to fungovalo.\n\nVy i váš kontakt musíte klepnout na \"Start\" ve stejný čas.</string> <item quantity="other">%d nových kontaktů bylo přidáno.</item>
<string name="connect_via_bluetooth_already_discovering">Již se pokoušíte o připojení přes Bluetooth. Zkuste to znovu za chvíli.</string> </plurals>
<string name="connect_via_bluetooth_no_location_permission">Není možné pokračovat bez povolení znát umístění</string>
<string name="connect_via_bluetooth_no_bluetooth_permission">Není možné pokračovat bez povolení přístupu k zařízením v okolí</string>
<string name="connect_via_bluetooth_start">Připojování přes Bluetooth...</string>
<string name="connect_via_bluetooth_success">Úspěšně připojeno přes Bluetooth</string>
<string name="connect_via_bluetooth_error">Nebylo možné se připojit přes Bluetooth.</string>
<string name="connect_via_bluetooth_error_not_supported">Bluetooth není podporován zařízením.</string>
<!--Private Groups--> <!--Private Groups-->
<string name="groups_list_empty">Žádné skupiny k zobrazení</string>
<string name="groups_list_empty_action">Klepněte na ikonu + pro vytvoření skupiny a nebo požádejte své kontakty, aby s vámi skupiny sdílely</string>
<string name="groups_created_by">Vytvořeno %s</string> <string name="groups_created_by">Vytvořeno %s</string>
<plurals name="messages"> <plurals name="messages">
<item quantity="one">%d zpráva</item> <item quantity="one">%d zpráva</item>
@@ -380,6 +179,7 @@
<string name="groups_create_group_invitation_button">Poslat pozvánku</string> <string name="groups_create_group_invitation_button">Poslat pozvánku</string>
<string name="groups_create_group_hint">Vyberte jméno pro vaši soukromou skupinu</string> <string name="groups_create_group_hint">Vyberte jméno pro vaši soukromou skupinu</string>
<string name="groups_invitation_sent">Skupinová pozvánka byla odeslána</string> <string name="groups_invitation_sent">Skupinová pozvánka byla odeslána</string>
<string name="groups_message_sent">Zpráva odeslána</string>
<string name="groups_member_list">Seznam členů</string> <string name="groups_member_list">Seznam členů</string>
<string name="groups_invite_members">Pozvat členy</string> <string name="groups_invite_members">Pozvat členy</string>
<string name="groups_member_created_you">Vytvořili jste skupinu</string> <string name="groups_member_created_you">Vytvořili jste skupinu</string>
@@ -409,7 +209,6 @@
</plurals> </plurals>
<string name="groups_invitations_response_accepted_sent">Přijali jste pozvání do skupiny od %s.</string> <string name="groups_invitations_response_accepted_sent">Přijali jste pozvání do skupiny od %s.</string>
<string name="groups_invitations_response_declined_sent">Odmítli jste pozvání do skupiny od %s.</string> <string name="groups_invitations_response_declined_sent">Odmítli jste pozvání do skupiny od %s.</string>
<string name="groups_invitations_response_declined_auto">Pozvánka do skupiny od %s byla automaticky zamítnuta.</string>
<string name="groups_invitations_response_accepted_received">%s přijatých pozvání ke skupině.</string> <string name="groups_invitations_response_accepted_received">%s přijatých pozvání ke skupině.</string>
<string name="groups_invitations_response_declined_received">%s odmítnutých pozvání ke skupině.</string> <string name="groups_invitations_response_declined_received">%s odmítnutých pozvání ke skupině.</string>
<string name="sharing_status_groups">Pouze zakladatel může pozvat nové členy do skupiny. Níže jsou všichni současní členové skupiny.</string> <string name="sharing_status_groups">Pouze zakladatel může pozvat nové členy do skupiny. Níže jsou všichni současní členové skupiny.</string>
@@ -421,8 +220,6 @@
<string name="groups_reveal_visible_revealed_by_contact">Vztah s kontaktem je viditelný ve skupině (byl odkrytý %s)</string> <string name="groups_reveal_visible_revealed_by_contact">Vztah s kontaktem je viditelný ve skupině (byl odkrytý %s)</string>
<string name="groups_reveal_invisible">Vztah s kontaktem není viditelný ve skupině</string> <string name="groups_reveal_invisible">Vztah s kontaktem není viditelný ve skupině</string>
<!--Forums--> <!--Forums-->
<string name="no_forums">Žádná fóra k zobrazení</string>
<string name="no_forums_action">Klepněte na ikonu + pro vytvoření fóra a nebo požádejte své kontakty, aby s vámi fóra sdílely</string>
<string name="create_forum_title">Vytvořit fórum</string> <string name="create_forum_title">Vytvořit fórum</string>
<string name="choose_forum_hint">Vybrat jméno pro vaše fórum</string> <string name="choose_forum_hint">Vybrat jméno pro vaše fórum</string>
<string name="create_forum_button">Vytvořit fórum</string> <string name="create_forum_button">Vytvořit fórum</string>
@@ -435,7 +232,6 @@
<item quantity="many">%d příspěvků</item> <item quantity="many">%d příspěvků</item>
<item quantity="other">%d příspěvků</item> <item quantity="other">%d příspěvků</item>
</plurals> </plurals>
<string name="forum_new_message_hint">Nový příspěvek</string>
<string name="forum_message_reply_hint">Nová odpověď</string> <string name="forum_message_reply_hint">Nová odpověď</string>
<string name="btn_reply">Odpověď</string> <string name="btn_reply">Odpověď</string>
<string name="forum_leave">Opustit fórum</string> <string name="forum_leave">Opustit fórum</string>
@@ -447,26 +243,18 @@
<string name="forum_share_button">Sdílet fórum</string> <string name="forum_share_button">Sdílet fórum</string>
<string name="contacts_selected">Zvolené kontakty</string> <string name="contacts_selected">Zvolené kontakty</string>
<string name="activity_share_toolbar_header">Zvolit kontakty</string> <string name="activity_share_toolbar_header">Zvolit kontakty</string>
<string name="no_contacts_selector">Žádné kontakty k zobrazení</string>
<string name="no_contacts_selector_action">Prosím vraťte se sem po přidání kontaktu</string>
<string name="forum_shared_snackbar">Fórum sdíleno s vybranými kontakty</string> <string name="forum_shared_snackbar">Fórum sdíleno s vybranými kontakty</string>
<string name="forum_share_message">Přidat zprávu (volitelné)</string> <string name="forum_share_message">Přidat zprávu (volitelné)</string>
<string name="forum_share_error">Při sdílení tohoto fóra nastala chyba.</string> <string name="forum_share_error">Při sdílení tohoto fóra nastala chyba.</string>
<string name="forum_invitation_received">%1$s sdílel fórum \"%2$s\" s vámi.</string> <string name="forum_invitation_received">%1$s sdílel fórum \"%2$s\" s vámi.</string>
<string name="forum_invitation_sent">Sdíleli jste fórum \"%1$s\" s %2$s.</string> <string name="forum_invitation_sent">Sdíleli jste fórum \"%1$s\" s %2$s.</string>
<string name="forum_invitations_title">Pozvání do fóra</string> <string name="forum_invitations_title">Pozvání do fóra</string>
<string name="forum_invitation_exists">Již jste přijali pozvání do tohoto fóra.\n\nPřijetí dalších pozvání zajistí rychlejší a spolehlivější připojení k fóru.</string>
<string name="forum_joined_toast">Vstup do fóra</string> <string name="forum_joined_toast">Vstup do fóra</string>
<string name="forum_declined_toast">Pozvání zamítnuto</string> <string name="forum_declined_toast">Pozvání zamítnuto</string>
<string name="shared_by_format">Sdíleno %s</string> <string name="shared_by_format">Sdíleno %s</string>
<string name="forum_invitation_already_sharing">Již sdílené</string> <string name="forum_invitation_already_sharing">Již sdílené</string>
<string name="forum_invitation_already_invited">Pozvánka již byla odeslána</string>
<string name="forum_invitation_invite_received">Pozvánka již byla obdržena</string>
<string name="forum_invitation_not_supported">Nepodporováno tímto kontaktem</string>
<string name="forum_invitation_error">Chyba. Jde o poruchu, která není vaší vinou</string>
<string name="forum_invitation_response_accepted_sent">Přijali jste pozvání do fóra od %s.</string> <string name="forum_invitation_response_accepted_sent">Přijali jste pozvání do fóra od %s.</string>
<string name="forum_invitation_response_declined_sent">Odmítli jste pozvání do fóra od %s.</string> <string name="forum_invitation_response_declined_sent">Odmítli jste pozvání do fóra od %s.</string>
<string name="forum_invitation_response_declined_auto">Pozvánka do fóra od %s byla automaticky zamítnuta.</string>
<string name="forum_invitation_response_accepted_received">%s přijatých pozvání do fóra.</string> <string name="forum_invitation_response_accepted_received">%s přijatých pozvání do fóra.</string>
<string name="forum_invitation_response_declined_received">%s odmítnutých pozvání do fóra.</string> <string name="forum_invitation_response_declined_received">%s odmítnutých pozvání do fóra.</string>
<string name="sharing_status">Sdílet status</string> <string name="sharing_status">Sdílet status</string>
@@ -489,9 +277,7 @@
<string name="blogs_blog_post_received">Přijatý nový příspěvek v blogu.</string> <string name="blogs_blog_post_received">Přijatý nový příspěvek v blogu.</string>
<string name="blogs_blog_post_scroll_to">Přejít na</string> <string name="blogs_blog_post_scroll_to">Přejít na</string>
<string name="blogs_feed_empty_state">Žádné příspěvky k zobrazení</string> <string name="blogs_feed_empty_state">Žádné příspěvky k zobrazení</string>
<string name="blogs_feed_empty_state_action">Příspěvky od vašich kontaktů a z blogů, které odebíráte se zobrazí zde\n\nKlepněte na ikonu pera pro napsání příspěvku</string>
<string name="blogs_remove_blog">Odstranit blog</string> <string name="blogs_remove_blog">Odstranit blog</string>
<string name="blogs_remove_blog_dialog_message">Jste si jisti, že chcete odebrat tento blog?\n\nPříspěvky budou smazány z vašeho zařízení ale ne ze zařízení ostatních lidí.\n\nKontakty, se kterými jste sdíleli tento blog mohou přestat dostávat aktualizace.</string>
<string name="blogs_remove_blog_ok">Odstranit</string> <string name="blogs_remove_blog_ok">Odstranit</string>
<string name="blogs_blog_removed">Blog odstraněn</string> <string name="blogs_blog_removed">Blog odstraněn</string>
<string name="blogs_reblog_comment_hint">Přidat komentář (volitelné)</string> <string name="blogs_reblog_comment_hint">Přidat komentář (volitelné)</string>
@@ -503,7 +289,6 @@
<string name="blogs_sharing_snackbar">Blog sdílen s vybranými kontakty.</string> <string name="blogs_sharing_snackbar">Blog sdílen s vybranými kontakty.</string>
<string name="blogs_sharing_response_accepted_sent">Přijali jste pozvání do blogu od %s.</string> <string name="blogs_sharing_response_accepted_sent">Přijali jste pozvání do blogu od %s.</string>
<string name="blogs_sharing_response_declined_sent">Odmítli jste pozvání do blogu od %s.</string> <string name="blogs_sharing_response_declined_sent">Odmítli jste pozvání do blogu od %s.</string>
<string name="blogs_sharing_response_declined_auto">Pozvánka k blogu od %s byla automaticky zamítnuta.</string>
<string name="blogs_sharing_response_accepted_received">%s schválených pozvání do blogu.</string> <string name="blogs_sharing_response_accepted_received">%s schválených pozvání do blogu.</string>
<string name="blogs_sharing_response_declined_received">%s odmítnutých pozvání do blogu.</string> <string name="blogs_sharing_response_declined_received">%s odmítnutých pozvání do blogu.</string>
<string name="blogs_sharing_invitation_received">%1$s sdílel blog \"%2$s\" s vámi.</string> <string name="blogs_sharing_invitation_received">%1$s sdílel blog \"%2$s\" s vámi.</string>
@@ -516,92 +301,59 @@
<string name="blogs_rss_feeds_import">Import RSS kanálu</string> <string name="blogs_rss_feeds_import">Import RSS kanálu</string>
<string name="blogs_rss_feeds_import_button">Import</string> <string name="blogs_rss_feeds_import_button">Import</string>
<string name="blogs_rss_feeds_import_hint">Zadejte URL adresu RSS kanálu</string> <string name="blogs_rss_feeds_import_hint">Zadejte URL adresu RSS kanálu</string>
<string name="blogs_rss_feeds_import_progress">Importování RSS kanálu...</string>
<string name="blogs_rss_feeds_import_error">Omlouváme se! Vyskytla se chyba při importu vašeho kanálu.</string> <string name="blogs_rss_feeds_import_error">Omlouváme se! Vyskytla se chyba při importu vašeho kanálu.</string>
<string name="blogs_rss_feeds_import_title">Importovat kanál ze souboru</string>
<string name="blogs_rss_feeds">RSS kanály</string>
<string name="blogs_rss_feeds_manage_imported">Importováno:</string> <string name="blogs_rss_feeds_manage_imported">Importováno:</string>
<string name="blogs_rss_feeds_manage_author">Autor:</string> <string name="blogs_rss_feeds_manage_author">Autor:</string>
<string name="blogs_rss_feeds_manage_updated">Naposledy aktualizováno:</string> <string name="blogs_rss_feeds_manage_updated">Naposledy aktualizováno:</string>
<string name="blogs_rss_remove_feed">Odstranit kanál</string> <string name="blogs_rss_remove_feed">Odstranit kanál</string>
<string name="blogs_rss_remove_feed_dialog_message">Jste si jisti, že chcete odebrat tento kanál?\n\nPříspěvky budou odebrány z vašeho zařízení ale zůstanou na zařízeních jiných lidí.\n\nKontakty, se kterými jste tento kanál sdíleli, mohou přestat dostávat aktualizace.</string>
<string name="blogs_rss_remove_feed_ok">Odstranit</string> <string name="blogs_rss_remove_feed_ok">Odstranit</string>
<string name="blogs_rss_feeds_manage_empty_state">Žádné RSS kanály k zobrazení\n\nKlikněte na ikonu + pro nahrání příspěvků</string> <string name="blogs_rss_feeds_manage_empty_state">Žádné RSS kanály k zobrazení\n\nKlikněte na ikonu + pro nahrání příspěvků</string>
<string name="blogs_rss_feeds_manage_error">Vyskytl se problém s načtením vašeho kanálu příspěvků. Zkuste to prosím později.</string> <string name="blogs_rss_feeds_manage_error">Vyskytl se problém s načtením vašeho kanálu příspěvků. Zkuste to prosím později.</string>
<!--Settings Profile Picture-->
<string name="change_profile_picture">Klepněte pro změnu svého profilového obrázku</string>
<string name="dialog_confirm_profile_picture_title">Změnit profilový obrázek</string>
<string name="dialog_confirm_profile_picture_remark">Pouze vaše kontakty uvidí tento obrázek</string>
<string name="change_profile_picture_failed_message">Omlouváme se, ale něco se pokazilo při aktualizaci vašeho profilového obrázku</string>
<!--Settings Display--> <!--Settings Display-->
<string name="pref_language_title">Jazyk a oblast</string> <string name="pref_language_title">Jazyk &amp; region</string>
<string name="pref_language_changed">Toto nastavení bude mít efekt když vykonáre restart svého Briar. Prosím odhlaste se a restartujte Briar.</string> <string name="pref_language_changed">Toto nastavení bude mít efekt když vykonáre restart svého Briar. Prosím odhlaste se a restartujte Briar.</string>
<string name="pref_language_default">Podle systému</string> <string name="pref_language_default">Výchozí systému</string>
<string name="display_settings_title">Zobrazení</string> <string name="display_settings_title">Zobrazit</string>
<string name="pref_theme_title">Vzhled</string> <string name="pref_theme_title">Vzhled</string>
<string name="pref_theme_light">Světlý</string> <string name="pref_theme_light">Světlý</string>
<string name="pref_theme_dark">Temný</string> <string name="pref_theme_dark">Temný</string>
<string name="pref_theme_auto">Automaticky (denní doba)</string> <!--Settings Network-->
<string name="pref_theme_system">Podle systému</string> <string name="network_settings_title">Sítě</string>
<!--Settings Connections--> <string name="bluetooth_setting">Spojení přes Bluetooth</string>
<string name="network_settings_title">Connections</string> <string name="bluetooth_setting_enabled">Vždy, když jsou kontakty v blízkosti</string>
<string name="bluetooth_setting">Připojit se ke kontaktům přes Bluetooth</string> <string name="bluetooth_setting_disabled">Jen když přidáte kontakty</string>
<string name="wifi_setting">Připojte se ke kontaktům na stejné Wi-Fi síti</string> <!--How and when Tor will connect after Automatic: E.g. Don't connect (in China) or Use Tor with bridges (in Belarus)-->
<string name="tor_enable_title">Připojte se ke kontaktům přes internet</string>
<string name="tor_enable_summary">Všechna spojení jdou skrze síť Tor kvůli soukromí</string>
<string name="tor_network_setting">Způsob připojení k síti Tor</string>
<string name="tor_network_setting_automatic">Automatické v závislosti na umístění</string>
<string name="tor_network_setting_without_bridges">Použít síť Tor bez mostů</string>
<string name="tor_network_setting_with_bridges">Použít síť Tor s mosty</string>
<string name="tor_network_setting_never">Nepřipojovat se k internetu</string>
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
<string name="tor_network_setting_summary">Automatické: %1$s (v %2$s)</string>
<string name="tor_mobile_data_title">Použít mobilní data</string>
<string name="tor_only_when_charging_title">Připojit se k internetu pouze při nabíjení</string>
<string name="tor_only_when_charging_summary">Vypne internetové připojení když zařízení není nabíjeno ze sítě</string>
<!--Settings Security and Panic--> <!--Settings Security and Panic-->
<string name="security_settings_title">Zabezpečení</string> <string name="security_settings_title">Zabezpečení</string>
<string name="pref_lock_title">Zamčení aplikace</string>
<string name="pref_lock_summary">Použít zamčení obrazovky zařízení pro ochranu Briaru po přihlášení</string>
<string name="pref_lock_disabled_summary">Pro použité této funkce nastavte zamčení obrazovky zařízení</string>
<string name="pref_lock_timeout_title">Doba neaktivity pro zamčení aplikace</string>
<!--The %s placeholder is replaced with the following time spans, e.g. 5 Minutes, 1 Hour--> <!--The %s placeholder is replaced with the following time spans, e.g. 5 Minutes, 1 Hour-->
<string name="pref_lock_timeout_summary">Když Briar není používán, automaticky ho zamknou po %s</string>
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"--> <!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
<string name="pref_lock_timeout_1">1 minutě</string>
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"--> <!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
<string name="pref_lock_timeout_5">5 minutách</string>
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"--> <!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
<string name="pref_lock_timeout_15">15 minutách</string>
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"--> <!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
<string name="pref_lock_timeout_30">30 minutách</string>
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"--> <!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
<string name="pref_lock_timeout_60">1 hodina</string> <string name="pref_lock_timeout_60">1 hodina</string>
<string name="pref_lock_timeout_never">Nikdy</string> <string name="pref_lock_timeout_never">Nikdy</string>
<string name="pref_lock_timeout_never_summary">Nikdy nezamykat Briar automaticky</string>
<string name="change_password">Změnit heslo</string> <string name="change_password">Změnit heslo</string>
<string name="current_password">Současné heslo</string> <string name="current_password">Současné heslo</string>
<string name="choose_new_password">Nové heslo</string> <string name="choose_new_password">Nové heslo</string>
<string name="confirm_new_password">Potvrdit nové heslo</string>
<string name="password_changed">Heslo bylo změněno.</string> <string name="password_changed">Heslo bylo změněno.</string>
<string name="panic_setting">Nastavení tlačítka paniky</string> <string name="panic_setting">Nastavení tlačítka Paniky</string>
<string name="panic_setting_title">Tlačítko paniky</string> <string name="panic_setting_title">Tlačítko Paniky</string>
<string name="panic_setting_hint">Nastavte, jak bude Briar reagovat, když použijete aplikaci tlačítka paniky</string> <string name="panic_setting_hint">Nastavte, jak bude Briar reagovat, když použijete aplikaci tlačítka paniky</string>
<string name="panic_app_setting_title">Aplikace paniky</string> <string name="panic_app_setting_title">Aplikace Panik tlačítko</string>
<string name="unknown_app">neznámá aplikace</string> <string name="unknown_app">neznámá aplikace</string>
<string name="panic_app_setting_summary">Žádná aplikace nebyla nastavena</string> <string name="panic_app_setting_summary">Žádná aplikace nebyla nastavena</string>
<string name="panic_app_setting_none">Žádný</string> <string name="panic_app_setting_none">Žádný</string>
<string name="dialog_title_connect_panic_app">Potvrdit aplikaci paniky</string> <string name="dialog_title_connect_panic_app">Potvrdit aplikaci Paniky</string>
<string name="dialog_message_connect_panic_app">Jste si jisti, že chcete povolit %1$s spustit akci zneškodnění pomocí tlačítka paniky?</string> <string name="dialog_message_connect_panic_app">Jste si jisti, že chcete povolit %1$s spustit akci zneškodnění pomocí tlačítka paniky?</string>
<string name="panic_setting_destructive_action">Destruktivní akce</string>
<string name="panic_setting_signout_title">Odhlásit se</string> <string name="panic_setting_signout_title">Odhlásit se</string>
<string name="panic_setting_signout_summary">Odhlásit se z Briar, pokud je stisknuto tlačítko paniky</string> <string name="panic_setting_signout_summary">Odhlásit se z Briar, pokud je stisknuto tlačítko paniky</string>
<string name="purge_setting_title">Odstranit účet</string> <string name="purge_setting_title">Odstranit účet</string>
<string name="purge_setting_summary">Při stisknutí tlačítka paniky odstranit váš účet Briar. Varování: tato akce trvale vymaže vaše identity, kontakty a zprávy</string> <string name="purge_setting_summary">Vymazat váš Briar účet pokud je stlačeno tlačítko paniky. Upozornění: Toto trvale vymaže vaši identitu, kontakty a zprávy</string>
<string name="uninstall_setting_title">Odinstalovat Briar</string>
<string name="uninstall_setting_summary">Toto vyžaduje manuální potvrzení v události paniky</string>
<!--Settings Notifications--> <!--Settings Notifications-->
<string name="notification_settings_title">Upozorně</string> <string name="notification_settings_title">Oznáme</string>
<string name="notify_sign_in_title">Připomenout mi, abych se přihlásil/a</string>
<string name="notify_sign_in_summary">Zobrazit připomínku po startu telefonu nebo po aktualizaci aplikace</string>
<string name="notify_private_messages_setting_title">Soukromé zprávy</string> <string name="notify_private_messages_setting_title">Soukromé zprávy</string>
<string name="notify_private_messages_setting_summary">Zobrazit upozornění pro soukromé zprávy</string> <string name="notify_private_messages_setting_summary">Zobrazit upozornění pro soukromé zprávy</string>
<string name="notify_private_messages_setting_summary_26">Nastavení upozornění pro soukromé zprávy</string> <string name="notify_private_messages_setting_summary_26">Nastavení upozornění pro soukromé zprávy</string>
@@ -620,116 +372,17 @@
<string name="notify_sound_setting_disabled">Žádný</string> <string name="notify_sound_setting_disabled">Žádný</string>
<string name="choose_ringtone_title">Zvolit vyzváněcí tón</string> <string name="choose_ringtone_title">Zvolit vyzváněcí tón</string>
<string name="cannot_load_ringtone">Nelze načíst vyzváněcí tón</string> <string name="cannot_load_ringtone">Nelze načíst vyzváněcí tón</string>
<!--Mailbox--> <!--Settings Feedback-->
<string name="mailbox_settings_title">Mailbox</string> <string name="feedback_settings_title">Zpětná vazba</string>
<string name="mailbox_setup_title">Mailbox nastavení</string>
<string name="mailbox_setup_intro">Mailbox umožňuje vašim kontaktům posílat vám zprávy když jste offline. Mailbox obdrží vaše zprávy a uchová je dokud nebudete online.\n
\nBriar Mailbox aplikaci můžete nainstalovat na nevyužité zařízení. Nechte ho připojené do elektrické sítě a k Wi-Fi aby bylo neustále online.</string>
<string name="mailbox_setup_download">Nejprve nainstalujte aplikaci Mailbox na jiné zařízení tak, že si vyhledáte \"Briar Mailbox\" na Google Play nebo jinde odkud stahujete Briar.\n
\nPotom spojte váš Mailbox s Briarem oskenováním QR kódu zobrazeném aplikací Mailbox.</string>
<string name="mailbox_setup_download_link">Sdílet odkaz pro stažení</string>
<string name="mailbox_setup_button_scan">Skenovat Mailbox QR kód</string>
<string name="permission_camera_qr_denied_body">Přístup k fotoaparátu máte zakázaný ale skenování QR kódu vyžaduje použití fotoaparátu.\n\nProsím zvažte povolení přístupu.</string>
<string name="mailbox_setup_connecting">Připojování k Mailboxu...</string>
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
<string name="mailbox_setup_connecting_info">Toto může trvat až %1s</string>
<string name="mailbox_qr_code_too_old">QR kód, který jste oskenovali, pochází ze starší verze Briar Mailboxu.\n\nProsím aktualizujte Briar Mailbox na nejnovější verzi a pak akci opakujte.</string>
<string name="mailbox_qr_code_too_new">QR kód, který jste oskenovali, pochází z novější verze Briar Mailboxu.\n\nProsím aktualizujte Briar Mailbox na nejnovější verzi a pak akci opakujte.</string>
<string name="contact_qr_code_for_mailbox">QR kód, který jste oskenovali, je určen k přidání kontaktu Briar.\n\nPokud chcete přidat kontakt, prosím jděte do seznamu kontaktů a klepněte na ikonu +.</string>
<string name="mailbox_setup_qr_code_wrong_description">QR kód, který jste oskenovali, nepochází z Briar Mailboxu.\n\nProsím otevřete Briar Mailbox aplikaci na vašem Mailbox zařízení a oskenujte QR kód který vám zobrazí.</string>
<string name="mailbox_setup_already_paired_title">Mailbox již byl spojen</string>
<string name="mailbox_setup_already_paired_description">Odpojte Mailbox na vašem dalším zařízení a akci opakujte.</string>
<string name="mailbox_setup_io_error_title">Nebylo možné se připojit</string>
<string name="mailbox_setup_io_error_description">Ujistěte se, že obě zařízení jsou připojena k internetu a akci opakujte.</string>
<string name="mailbox_setup_assertion_error_title">Chyba Mailboxu</string>
<string name="mailbox_setup_assertion_error_description">Pokud problém přetrvává, použijte prosím aplikaci Briar k odeslání zpětné vazby (s anonymizovanými daty).</string>
<string name="mailbox_setup_camera_error_description">Nebylo možné získat přístup k fotoaparátu. Možná zkuste restartovat zařízení a opakovat akci.</string>
<string name="mailbox_setup_paired_title">Připojeno</string>
<string name="mailbox_setup_paired_description">Váš Mailbox byl úspěšně spojen s Briarem.\n
\nNechte Mailbox připojený k elektrické síti a k Wi-Fi aby byl neustále online.</string>
<string name="tor_offline_title">Offline</string>
<string name="tor_offline_description">Ujistěte se, že toto zařízení je online a přístup k internetu je povolen.\n
\nNásledně vyčkejte až se ikona zeměkoule změní na zelenou.</string>
<string name="tor_offline_button_check">Zkontrolujte nastavení připojení</string>
<string name="mailbox_status_title">Stav Mailboxu</string>
<string name="mailbox_status_connected_title">Mailbox běží</string>
<string name="mailbox_status_problem_title">Briar má problém s připojením k Mailboxu</string>
<string name="mailbox_status_failure_title">Mailbox je nedostupný</string>
<string name="mailbox_status_app_too_old_title">Briar je příliš zastaralý</string>
<string name="mailbox_status_app_too_old_message">Aktualizujte Briar na nejnovější verzi aplikace a opakujte akci.</string>
<string name="mailbox_status_mailbox_too_old_title">Mailbox je příliš zastaralý</string>
<string name="mailbox_status_mailbox_too_old_message">Aktualizujte váš Mailbox na nejnovější verzi aplikace a zkuste to znovu.</string>
<string name="mailbox_status_check_button">Zkontrolujte připojení</string>
<!--Example for string substitution: Last connection: 3min ago-->
<string name="mailbox_status_connected_info">Poslední připojení: %s</string>
<!--Indicates that there never was a connection to the mailbox. Last connection: Never-->
<string name="mailbox_status_connected_never">Nikdy</string>
<string name="mailbox_status_unlink_button">Odpojit</string>
<string name="mailbox_status_unlink_dialog_title">Odpojit Mailbox?</string>
<string name="mailbox_status_unlink_dialog_question">Jste si jisti, že si přejete odpojit váš Mailbox?</string>
<string name="mailbox_status_unlink_dialog_warning">Pokud odpojíte svůj Mailbox, nebudete moci obdržet zprávy když bude Briar nedostupný/offline.</string>
<string name="mailbox_status_unlink_no_wipe_title">Váš Mailbox byl odpojen</string>
<string name="mailbox_status_unlink_no_wipe_message">Až budete mít příště přístup do vašeho Mailbox zařízení, otevřete prosím Mailbox aplikaci a klepněte na tlačítko \"Odpojit\" pro dokončení procesu.\n\nPokud již nemáte přístup k vašemu Mailbox zařízení, nezoufejte. Vaše data jsou šifrována, takže zůstanou v bezpečí i v případě, že proces nedokončíte.</string>
<string name="mailbox_status_unlink_success">Váš Mailbox byl odpojen</string>
<string name="mailbox_error_notification_channel_title">Problém s Briar Mailboxem</string>
<string name="mailbox_error_notification_title">Briar Mailbox je nedostupný</string>
<string name="mailbox_error_notification_text">Klepněte pro vyřešení problému.</string>
<string name="mailbox_error_wizard_button">Vyřešit problém</string>
<string name="mailbox_error_wizard_title">Průvodce řešení problémů s Mailboxem</string>
<string name="mailbox_error_wizard_question1">Máte přístup k vašemu Mailbox zařízení?</string>
<string name="mailbox_error_wizard_answer1">Ano, mám k němu nyní přístup.</string>
<string name="mailbox_error_wizard_answer2">Nyní k němu nemám přístup ale budu ho mít později.</string>
<string name="mailbox_error_wizard_answer3">Ne, již k němu nemám přístup.</string>
<string name="mailbox_error_wizard_info1_1">Zkontrolujte, že Mailbox zařízení je zapnuto a připojeno k internetu.</string>
<string name="mailbox_error_wizard_question1_1">Otevřete Mailbox aplikaci. Co vidíte?</string>
<string name="mailbox_error_wizard_answer1_1">Vidím instrukce k nastavení Mailboxu</string>
<string name="mailbox_error_wizard_answer1_2">Vidím QR kód</string>
<string name="mailbox_error_wizard_answer1_3">Vidím \"Mailbox běží\"</string>
<string name="mailbox_error_wizard_answer1_4">Vidím \"Zařízení je nedostupné\"</string>
<string name="mailbox_error_wizard_info1_1_1">Prosím odpojte váš Mailbox pomocí tlačítka níže, potom postupujte podle instrukcí na Mailbox zařízení pro opětovné spojení.</string>
<string name="mailbox_error_wizard_info_1_1_2">Prosím odpojte váš Mailbox pomocí tlačítka níže, potom oskenujte QR kód pro opětovné spojení.</string>
<string name="mailbox_error_wizard_info1_1_3">Prosím, použijte tlačítko níže pro kontrolu spojení mezi Briarem a Mailboxem.\n\n
Pokud spojení znovu selže:\n
\u2022 Zkontrolujte, že Mailbox a Briar aplikace jsou aktualizované na nejnovější verzi.\n
\u2022 Restartujte Mailbox a Briar zařízení a zkuste to znovu.</string>
<string name="mailbox_error_wizard_info1_1_4">Zkontrolujte že mailbox zařízení je správně připojeno k internetu.\n\nZkontrolujte že hodiny na Mailbox zařízení ukazují správný čas, datum a časové pásmo.\n\nZkontrolujte že Mailbox a Briar aplikace jsou aktualizované na nejnovější verzi.\n\nRestartujte Mailbox i Briar zařízení a zkuste to znovu.</string>
<string name="mailbox_error_wizard_info2">Prosím vraťte se zpět na tuto obrazovku jakmile získáte přístup k zařízení.</string>
<string name="mailbox_error_wizard_info3">Prosím odpojte váš Mailbox pomocí tlačítka níže.\n\nPo odpojení vašeho starého Mailboxu můžete kdykoliv nastavit nový Mailbox.</string>
<!--About-->
<string name="about_title">O</string>
<string name="briar_version">Briar verze: %s</string>
<string name="tor_version">Tor verze: %s</string>
<string name="links">Odkazy</string>
<string name="briar_website">\u2022 <a href="">Webová stránka</a></string>
<string name="briar_source_code">\u2022 <a href="">Zdrojový kód</a></string>
<string name="briar_changelog">\u2022 <a href="">Změny v aplikaci</a></string>
<string name="briar_privacy_policy">\u2022 <a href="">Zásady ochrany osobních údajů</a></string>
<!--Here translators can add their names or Transifex usernames(eg "Thanks to all the contributors at the Localization Lab, especially Tom, Matthew and Jerry")-->
<string name="translator_thanks">Díky všem, kdo přispěli k překladu aplikace na https://www.transifex.com/otf/briar</string>
<!--Conversation Settings-->
<string name="disappearing_messages_title">Mizející zprávy</string>
<string name="disappearing_messages_explanation_long">Zapnutím této volby znamená, že nové
zprávy v této konverzaci automaticky zmizí po 7\u00A0dnech.
\n\nOdpočítávání pro kopii zprávy odesilatele začíná po jejím doručení.
Odpočítávání začíná pro příjemce po tom, co si zprávu přečtou.
\n\nZprávy, které zmizí jsou označeny ikonou bomby.
\n\nBerte na vědomí, že odesilatelé stále mohou vytvářet kopie vámi odeslaných zpráv.
\n\nPokud změníte tuto volbu, bude použita na vaše nové zprávy okamžitě a na
zprávy vašich kontaktů jakmile obdrží vaši další zprávu.
Váš kontakt také může změnit tuto volbu pro oba z vás.</string>
<string name="learn_more">Zjistit více</string>
<string name="disappearing_messages_summary">Nastavte automatické zmizení zpráv této konverzace po 7\u00A0dnech.</string>
<!--Settings Actions-->
<string name="pref_category_actions">Akce</string>
<string name="send_feedback">Poslat zpětnou vazbu</string> <string name="send_feedback">Poslat zpětnou vazbu</string>
<!--Link Warning--> <!--Link Warning-->
<string name="link_warning_title">Odkaz varování</string> <string name="link_warning_title">Odkaz varování</string>
<string name="link_warning_intro">Chystáte se otevřít následující odkaz pomocí externí eplikace.</string> <string name="link_warning_intro">Chystáte se otevřít následující odkaz pomocí externí eplikace.</string>
<string name="link_warning_text">Toto může být použito k vaší identifikaci. Zamyslete se, zda věříte osobě, která vám poslala tento odkaz a zvažte otevření pomocí Prohlížeče Tor.</string> <string name="link_warning_text">Toto může být užito pro vaší identifikaci. Přemýšlejte o tom, zda věřujete osobě, která vám poslala tento odkaz, a zvažte, zda ho otevřete s aplikací Orfox.</string>
<string name="link_warning_open_link">Otevřít odkaz</string> <string name="link_warning_open_link">Otevřít odkaz</string>
<!--Crash Reporter--> <!--Crash Reporter-->
<string name="crash_report_title">Hlášení o pádu Briar</string> <string name="crash_report_title">Hlášení o pádu Briar</string>
<string name="briar_crashed">Omlouváme se, Briar se zhroutil</string> <string name="briar_crashed">Promiňte, Briar se zhroutil.</string>
<string name="not_your_fault">Toto není vaše chyba.</string> <string name="not_your_fault">Toto není vaše chyba.</string>
<string name="please_send_report">Vaše pomoc je důležitá. Díky ní můžeme postavit lepší Briar tím, že nám pošlete zprávu o pádu aplikace.</string> <string name="please_send_report">Vaše pomoc je důležitá. Díky ní můžeme postavit lepší Briar tím, že nám pošlete zprávu o pádu aplikace.</string>
<string name="report_is_encrypted">Slibujeme, že hlášení je zašifrováno a bezpečně odesláno.</string> <string name="report_is_encrypted">Slibujeme, že hlášení je zašifrováno a bezpečně odesláno.</string>
@@ -737,164 +390,29 @@
<string name="describe_crash">Popište, co se stalo (nepovinné)</string> <string name="describe_crash">Popište, co se stalo (nepovinné)</string>
<string name="enter_feedback">Vložte svou zpětnou vazbu</string> <string name="enter_feedback">Vložte svou zpětnou vazbu</string>
<string name="optional_contact_email">Vaše emailová adresa (nepovinné)</string> <string name="optional_contact_email">Vaše emailová adresa (nepovinné)</string>
<string name="privacy_policy">Tím, že nám odešlete data, souhlasíte s našimi <a href="">zásadami ochrany osobních údajů</a></string>
<string name="include_debug_report_crash">Zahrnout anonymní data o tomto selhání</string> <string name="include_debug_report_crash">Zahrnout anonymní data o tomto selhání</string>
<string name="include_debug_report_feedback">Zahrnout anonymní data o tomto zařízení</string> <string name="include_debug_report_feedback">Zahrnout anonymní data o tomto zařízení</string>
<string name="dev_report_user_info">Informace o uživateli</string> <string name="could_not_load_report_data">Data hlášení nemohla být načtena.</string>
<string name="dev_report_basic_info">Základní údaje</string>
<string name="dev_report_device_info">Informace o zařízení</string>
<string name="dev_report_stacktrace">Stacktrace</string>
<string name="dev_report_time_info">Informace o času</string>
<string name="dev_report_memory">Paměť</string>
<string name="dev_report_storage">Úložiště</string>
<string name="dev_report_connectivity">Konektivita</string>
<string name="dev_report_network_usage">Využití sítě</string>
<string name="dev_report_build_config">Konfigurace sestavení</string>
<string name="dev_report_logcat">Log aplikace</string>
<string name="dev_report_device_features">Vlastnosti zařízení</string>
<string name="send_report">Odeslat hlášení</string> <string name="send_report">Odeslat hlášení</string>
<string name="close">Zavřít</string> <string name="close">Zavřít</string>
<string name="dev_report_sending">Odesílání zpětné vazby...</string>
<string name="dev_report_sent">Zpětná vazba odeslána</string>
<string name="dev_report_saved">Hlášení uloženo. Odesláno bude při příštím přihlášení do Briar.</string> <string name="dev_report_saved">Hlášení uloženo. Odesláno bude při příštím přihlášení do Briar.</string>
<string name="dev_report_error">Chyba: Odesílání hlášení selhalo</string>
<!--Sign Out--> <!--Sign Out-->
<string name="progress_title_logout">Odhlásit se z Briar...</string> <string name="progress_title_logout">Odhlásit se z Briar...</string>
<!--Screen Filters & Tapjacking--> <!--Screen Filters & Tapjacking-->
<string name="screen_filter_title">Bylo zjištěno překrytí obrazovky</string> <string name="screen_filter_title">Bylo zjištěno překrytí obrazovky</string>
<string name="screen_filter_body">Jiná aplikace se nachází nad aplikací Briar. Kvůli ochraně vaší bezpečnosti Briar nebude odpovídat na klepnutí prstem pokud jiná aplikace je na popředí.\n\nNásledující aplikace mohou být na popředí:\n\n%1$s</string>
<string name="screen_filter_body_api_30">Jiná aplikace se nachází nad aplikací Briar. Kvůli ochraně vaší bezpečnosti Briar nebude odpovídat na klepnutí prstem pokud jiná aplikace je na popředí.\n\nZkontrolujte níže uvedené aplikace abyste našli dotyčnou aplikaci.</string>
<string name="screen_filter_allow">Povolit těmto aplikacím zůstat navrchu</string> <string name="screen_filter_allow">Povolit těmto aplikacím zůstat navrchu</string>
<string name="screen_filter_review_apps">Zkontrolujte aplikace</string>
<!--Permission Requests--> <!--Permission Requests-->
<string name="permission_camera_title">Oprávnění pro přístup k fotoaparátu</string> <string name="permission_camera_title">Oprávnění pro přístup k fotoaparátu</string>
<string name="permission_camera_request_body">Pro scan QR kódu, Briar vyžaduje přístup k fotoaparátu.</string> <string name="permission_camera_request_body">Pro scan QR kódu, Briar vyžaduje přístup k fotoaparátu.</string>
<string name="permission_location_title">Místní povolení</string>
<string name="permission_location_request_body">Aby mohl Briar najít zařízení Bluetooth, potřebuje Briar povolení zjistit vaše umístění.\n\nBriar neukládá vaše umístění ani ho s nikým nesdílí.</string>
<string name="permission_camera_location_title">Fotoaparát a umístění</string>
<string name="permission_camera_location_request_body">Pro oskenování QR kódu potřebuje Briar přístup k fotoaparátu.\n\nPro nalezení zařízení Bluetooth potřebuje Briar povolení zjistit vaše umístění.\n\nBriar neukládá vaše umístění ani ho s nikým nesdílí.</string>
<string name="permission_camera_bluetooth_title">Fotoaparát a zařízení v okolí</string>
<string name="permission_camera_bluetooth_request_body">Pro oskenování QR kódu Briar potřebuje přístup k vašemu fotoaparátu.\n\nPro nalezení Bluetooth zařízení potřebuje Briar povolení přístupu k zařízením v okolí.</string>
<string name="permission_camera_denied_body">Odmítli jste udělit oprávnění přístupu k fotoaparátu, avšak pro přidání kontaktů je nutné použití fotoaparátu.\n\nZvažte prosím, opětovné udělení přístupu.</string> <string name="permission_camera_denied_body">Odmítli jste udělit oprávnění přístupu k fotoaparátu, avšak pro přidání kontaktů je nutné použití fotoaparátu.\n\nZvažte prosím, opětovné udělení přístupu.</string>
<string name="permission_location_denied_body">Zamítli jste přístup k umístění ale Briar tento přístup potřebuje k nalezení zařízení Bluetooth.\n\nZvažte povolení přístupu.</string>
<string name="permission_location_setting_title">Volba umístění</string>
<string name="permission_location_setting_body">Volba umístění vašeho zařízení musí být zapnuta aby byla nalezena jiná zařízení přes Bluetooth. Prosím zapněte umístění pro pokračování. Následně ho můžete zase vypnout.</string>
<string name="permission_location_setting_hotspot_body">Volba umístění vašeho zařízení musí být zapnuta aby mohl být vytvořen Wi-Fi hotspot. Prosím zapněte umístění pro pokračování. Následně ho můžete zase vypnout.</string>
<string name="permission_location_setting_button">Zapnout umístění</string>
<string name="permission_bluetooth_title">Povolení pro zařízení v okolí</string>
<string name="permission_bluetooth_body">Pro využití Bluetooth komunikace potřebuje Briar povolení hledat a spojovat se se zařízeními v okolí.</string>
<string name="permission_bluetooth_denied_body">Zamítli jste přístup k zařízením v okolí. Briar ale potřebuje tento přístup pro použití Bluetooth.\n\nProsím zvažte povolení přístupu.</string>
<string name="qr_code">QR kód</string> <string name="qr_code">QR kód</string>
<string name="show_qr_code_fullscreen">Zobrazit QR kód na celou obrazovku</string> <string name="show_qr_code_fullscreen">Zobrazit QR kód na celou obrazovku</string>
<!--App Locking--> <!--App Locking-->
<string name="lock_unlock">Odemknout Briar</string>
<string name="lock_unlock_verbose">K odemknutí aplikace Briar zadejte PIN, vzor nebo heslo vašeho zařízení</string>
<string name="lock_unlock_fingerprint_description">Pro pokračování se dotkněte snímače otisku prstu registrovaným prstem</string>
<string name="lock_unlock_password">Použít heslo</string>
<string name="lock_is_locked">Briar je zamčen</string>
<string name="lock_tap_to_unlock">Klepněte pro odemčení</string>
<!--Connections Screen-->
<string name="transports_help_text">Briar se může připojit k vašim kontaktům pomocí internetu, Wi-Fi nebo Bluetooth.\n\nVšechna internetová spojení jsou kvůli soukromí přenášena sítí Tor.\n\nPokud kontakt může být dosažen pomocí několika metod, Briar je využije zároveň.</string>
<!--Share app offline-->
<string name="hotspot_title">Sdílet tuto aplikaci offline</string>
<string name="hotspot_intro">Sdílejte tuto aplikaci s někým, kdo je blízko bez použití internetu, jen pomocí místní Wi-Fi sítě.
\n\nVáš telefon vytvoří Wi-Fi hotspot. Lidé v okolí se budou moci připojit k hotspotu a stáhnout aplikaci Briar z vašeho telefonu.</string>
<string name="hotspot_button_start_sharing">Spustit hotspot</string>
<string name="hotspot_button_stop_sharing">Zastavit hotspot</string>
<string name="hotspot_progress_text_start">Nastavování hotspotu...</string>
<string name="hotspot_notification_channel_title">Wi-Fi hotspot</string>
<string name="hotspot_notification_title">Sdílení Briaru offline</string>
<string name="hotspot_button_connected">Další</string>
<string name="permission_hotspot_location_request_body">Pro vytvoření Wi-Fi hotspotu potřebuje Briar povolení zjistit vaše umístění.\n\nBriar neukládá vaše umístění ani ho s nikým nesdílí.</string>
<string name="permission_hotspot_location_request_precise_body">Pro vytvoření Wi-Fi hotspotu potřebuje Briar povolení zjistit vaše přesné umístění.\n\nBriar neukládá vaše umístění ani ho s nikým nesdílí.</string>
<string name="permission_hotspot_location_denied_body">Zamítli jste přístup k vašemu umístění. Briar přístup potřebuje, aby mohl vytvořit Wi-Fi hotspot.\n\nProsím zvažte povolení přístupu.</string>
<string name="permission_hotspot_location_denied_precise_body">Zamítli jste přístup k vašemu přesnému umístění. Briar přístup potřebuje, aby mohl vytvořit Wi-Fi hotspot.\n\nProsím zvažte povolení přístupu.</string>
<string name="wifi_settings_title">Wi-Fi volba</string>
<string name="wifi_settings_request_enable_body">Pro vytvoření Wi-Fi hotspotu potřebuje Briar využít Wi-Fi. Prosím zapněte ji.</string>
<string name="hotspot_tab_manual">Manuálně</string>
<!--The placeholder to be inserted into the string 'hotspot_manual_wifi': People can connect by %s-->
<string name="hotspot_scanning_a_qr_code">oskenováním QR kódu</string>
<!--Wi-Fi setup-->
<!--The %s placeholder will be replaced with the translation of 'hotspot_scanning_a_qr_code'-->
<string name="hotspot_manual_wifi">Váš telefon poskytuje Wi-Fi hotspot. Lidé, kteří si chtějí stáhnout Briar se mohou k hotspotu připojit tak, že ho přidají ve Wi-Fi nastavení svého zařízení, za použití údajů uvedených níže a nebo %s. Jakmile se připojí k hotspotu, klikněte na \'Další\'.</string>
<string name="hotspot_manual_wifi_ssid">Název sítě</string>
<string name="hotspot_qr_wifi">Váš telefon poskytuje Wi-Fi hotspot. Lidé, kteří si chtějí stáhnout Briar se mohou k hotspotu připojit tak, že oskenují tento QR kód. Jakmile se připojí k hotspotu, klikněte na \'Další\'.</string>
<string name="hotspot_no_peers_connected">Nejsou připojena žádná zařízení</string>
<plurals name="hotspot_peers_connected">
<item quantity="one">%s zařízení připojeno</item>
<item quantity="few">%s zařízení připojena</item>
<item quantity="many">%s zařízení připojeno</item>
<item quantity="other">%s zařízení připojeno</item>
</plurals>
<!--Download link-->
<!--The %s placeholder will be replaced with the translation of 'hotspot_scanning_a_qr_code'-->
<string name="hotspot_manual_site">Váš telefon poskytuje Wi-Fi hotspot. Lidé, kteří jsou připojeni k hotspotu si mohou stáhnout Briar tak, že zadají následující odkaz do internetového prohlížeče nebo %s.</string>
<string name="hotspot_manual_site_address">Adresa (URL)</string>
<string name="hotspot_qr_site">Váš telefon poskytuje Wi-Fi hotspot. Lidé, kteří jsou připojeni k hotspotu si mohou stáhnout Briar po oskenování tohoto QR kódu.</string>
<!--e.g. Download Briar 1.2.20-->
<string name="website_download_title_1">Stáhnout Briar %s</string>
<string name="website_download_intro_1">Někdo v okolí s vámi sdílel Briar.</string>
<string name="website_download_button">Stáhnout Briar</string>
<string name="website_download_outro">Po tom, co stahování skončí, otevřete stažený soubor a nainstalujte ho.</string>
<string name="website_troubleshooting_title">Odstraňování problémů</string>
<string name="website_troubleshooting_1">Pokud nemůžete aplikaci stáhnout, zkuste použít jiný internetový prohlížeč.</string>
<string name="website_troubleshooting_2_old">Pro instalaci stažené aplikace možná bude nutné v nastavení systému povolit instalaci aplikací z neznámých zdrojů. Následně může být potřeba aplikaci znovu stáhnout. Po instalaci aplikace doporučujeme vypnout zmíněnou volbu neznámých zdrojů.</string>
<string name="website_troubleshooting_2_new">Pro instalaci stažené aplikace možná bude nutné v nastavení internetového prohlížeče povolit instalaci aplikací z neznámých zdrojů. Po instalaci aplikace doporučujeme vypnout zmíněnou volbu instalace neznámých aplikací.</string>
<string name="hotspot_help_wifi_title">Potíže s připojením k Wi-Fi:</string>
<string name="hotspot_help_wifi_1">Zkuste vypnout a zapnout Wi-Fi na obou telefonech a zkusit to znovu.</string>
<string name="hotspot_help_wifi_2">Pokud si váš telefon stěžuje, že Wi-Fi není připojena k internetu, vyberte i tak volbu zachování připojení k Wi-Fi.</string>
<string name="hotspot_help_wifi_3">Restartujte telefon, který provozuje Wi-Fi hotspot. Spusťte Briar a akci opakujte.</string>
<string name="hotspot_help_site_title">Potíže při navštívení místní webové stránky:</string>
<string name="hotspot_help_site_1">Dobře zkontrolujte, že jste zadali adresu přesně tak, jak je zobrazena. Malá chyba může způsobit selhání.</string>
<string name="hotspot_help_site_2">Ujistěte se, že váš telefon je stále připojen ke správně síti Wi-Fi (viz. výše) ve chvíli, kdy se pokoušíte přistoupit na stránku.</string>
<string name="hotspot_help_site_3">Pokud používáte firewall aplikaci, zkontrolujte že neblokuje přístup.</string>
<string name="hotspot_help_site_4">Pokud můžete navštívit stránku, ale stahování aplikace Briar nefunguje, zkuste to s jiným internetovým prohlížečem.</string>
<string name="hotspot_help_fallback_title">Nic nefunguje?</string>
<string name="hotspot_help_fallback_intro">Můžete zkusit uložit aplikaci jako .apk soubor a sdílet i jinými způsoby. Po přenesení souboru na jiné zařízení je možné ho využít k instalaci Briaru.
\n\nTip: Pro sdílení přes Bluetooth může být potřeba nejprve soubor přejmenovat aby končil příponou .zip.</string>
<string name="hotspot_help_fallback_button">Uložit aplikaci</string>
<!--error handling-->
<string name="hotspot_error_intro">Něco se pokazilo při pokusu o sdílení aplikace přes Wi-Fi:</string>
<string name="hotspot_error_no_wifi_direct">Zařízení nepodporuje Wi-Fi Direct</string>
<string name="hotspot_error_start_callback_failed">Hotspot se nespustil: chyba %s</string>
<string name="hotspot_error_start_callback_failed_unknown">Hotspot se nespustil kvůli neznámé chybě, důvod %d</string>
<string name="hotspot_error_start_callback_no_group_info">Spuštění hotspotu selhalo: žádné info skupiny</string>
<string name="hotspot_error_web_server_start">Chyba spuštění web serveru</string>
<string name="hotspot_error_web_server_serve">Chyba představení webové stránky.\n\nPokud problém přetrvává, prosím odešlete zpětnou vazbu (s anonymizovanými daty) pomocí aplikace Briar.</string>
<string name="hotspot_flag_test">Varování: Tato aplikace byla instalována pomocí Android Studia a NEMŮŽE být instalována na jiném zařízení.</string>
<string name="hotspot_error_framework_busy">Nebylo možné spustit hotspot.\n\nPokud máte spuštěný jiný hotspot a nebo sdílíte své internetové připojení pomocí Wi-Fi, zkuste to vypnout a pak akci opakovat.</string>
<!--Transfer Data via Removable Drives-->
<string name="removable_drive_menu_title">Připojit se přes vyměnitelný disk</string>
<string name="removable_drive_intro">Pokud se nemůžete připojit k vašemu kontaktu pomocí internetu, Wi-Fi nebo Bluetooth, Briar může také přenést zprávy na vyměnitelný disk, kterým je například USB klíčenka a nebo SD karta.</string>
<string name="removable_drive_explanation">Pokud se nemůžete připojit k vašemu kontaktu pomocí internetu, Wi-Fi nebo Bluetooth, Briar může také přenést zprávy na vyměnitelný disk, kterým je například USB klíčenka a nebo SD karta.\n\nKdyž použijete tlačítko \"Poslat data\", budou data čekající na odeslání kontaktům, zapsána na vyměnitelný disk. Tato data zahrnují soukromé zprávy, přílohy, blogy, fóra a soukromé skupiny.\n\nVše bude zašifrováno před zapsáním na vyměnitelný disk.\n\nJakmile kontakt obdrží vyměnitelný disk, může použít tlačítko \"Přijmout data\" a tím importovat zprávy do Briaru.</string>
<string name="removable_drive_title_send">Poslat data</string>
<string name="removable_drive_title_receive">Přijmout data</string>
<string name="removable_drive_send_intro">Klepněte na tlačítko níže pro vytvoření nového souboru obsahujícího šifrované zprávy. Můžete si zvolit kam bude soubor uložen.\n\nPokud chcete uložit soubor na vyměnitelný disk, tak ho nyní připojte.</string>
<string name="removable_drive_send_no_data">Nyní zde nejsou žádné zprávy čekající na odeslání tomuto kontaktu.</string>
<string name="removable_drive_send_not_supported">Tento kontakt používá starou verzi Briar a nebo staré zařízení, které nepodporuje tuto funkci.</string>
<string name="removable_drive_send_button">Vyberte soubor k exportu</string>
<string name="removable_drive_ongoing">Prosím čekejte až bude probíhající úloha dokončena</string>
<string name="removable_drive_receive_intro">Klepněte na tlačítko níže pro výběr souboru, který vám zaslal kontakt.\n\nPokud je soubor na vyměnitelném disku, tak disk nyní připojte.</string>
<string name="removable_drive_receive_button">Vyberte soubor k importu</string>
<string name="removable_drive_success_send_title">Export úspěšný</string>
<string name="removable_drive_success_send_text">Data byla úspěšně exportována. Nyní máte 28 dnů na přenos souboru vašemu kontaktu.\n\nPokud je soubor na vyměnitelném disku, použijte oznamovací oblast ve stavovém řádku pro bezpečné odebrání disku před odpojením.</string>
<string name="removable_drive_success_receive_title">Import byl úspěšný</string>
<string name="removable_drive_success_receive_text">Všechny šifrované zprávy obsažené v tomto souboru byly přijaty.</string>
<string name="removable_drive_error_send_title">Chyba při exportu dat</string>
<string name="removable_drive_error_send_text">Došlo k chybě při zápisu dat do souboru.\n\nPokud používáte vyměnitelný disk, ujistěte se že je správně vložen a akci opakujte.\n\nPokud chyba přetrvává, prosím informujte o problému Briar team odesláním zpětné vazby.</string>
<string name="removable_drive_error_receive_title">Chyba importu dat</string>
<string name="removable_drive_error_receive_text">Vybraný soubor neobsahoval nic co by Briar rozpoznal.\n\nProsím zkontrolujte, že jste vybrali správný soubor.\n\nPokud váš kontakt vytvořil soubor před více než 28 dny, Briar ho nebude moci rozpoznat.</string>
<!--Screenshots--> <!--Screenshots-->
<!--This is a name to be used in screenshots. Feel free to change it to a local name.--> <!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
<string name="screenshot_alice">Alice</string>
<!--This is a name to be used in screenshots. Feel free to change it to a local name.--> <!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
<string name="screenshot_bob">Tomáš</string>
<!--This is a name to be used in screenshots. Feel free to change it to a local name.--> <!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
<string name="screenshot_carol">Karolína</string>
<!--This is a message to be used in screenshots. Please use the same translation for Bob!--> <!--This is a message to be used in screenshots. Please use the same translation for Bob!-->
<string name="screenshot_message_1">Ahoj Tomáši!</string>
<!--This is a message to be used in screenshots. Please use the same translation for Alice!--> <!--This is a message to be used in screenshots. Please use the same translation for Alice!-->
<string name="screenshot_message_2">Ahoj Alice! Díky, že jsi mi dala vědět o Briaru!</string>
<!--This is a message to be used in screenshots.--> <!--This is a message to be used in screenshots.-->
<string name="screenshot_message_3">V pořádku, doufám že se ti líbí 😀</string>
</resources> </resources>

View File

@@ -60,8 +60,8 @@
<string name="old_android_expiry_date_reached">Briar wird auf Android 4 nicht mehr unterstützt.\nBitte installiere Briar auf einem neueren Gerät.</string> <string name="old_android_expiry_date_reached">Briar wird auf Android 4 nicht mehr unterstützt.\nBitte installiere Briar auf einem neueren Gerät.</string>
<string name="old_android_delete_account">Du kannst auf die Schaltfläche unten tippen, um dein Konto von diesem Gerät zu löschen.</string> <string name="old_android_delete_account">Du kannst auf die Schaltfläche unten tippen, um dein Konto von diesem Gerät zu löschen.</string>
<string name="delete_account_button">Konto löschen</string> <string name="delete_account_button">Konto löschen</string>
<string name="startup_open_database">Datenbank wird entschlüsselt</string> <string name="startup_open_database">Datenbank wird entschlüsselt...</string>
<string name="startup_migrate_database">Datenbank wird aktualisiert</string> <string name="startup_migrate_database">Datenbank wird aktualisiert...</string>
<string name="startup_compact_database">Datenbank wird komprimiert…</string> <string name="startup_compact_database">Datenbank wird komprimiert…</string>
<!--Navigation Drawer--> <!--Navigation Drawer-->
<string name="nav_drawer_open_description">Navigationsleiste öffnen</string> <string name="nav_drawer_open_description">Navigationsleiste öffnen</string>
@@ -234,7 +234,6 @@
<string name="exchanging_contact_details">Kontaktdetails werden ausgetauscht\u2026</string> <string name="exchanging_contact_details">Kontaktdetails werden ausgetauscht\u2026</string>
<string name="contact_added_toast">Kontakt hinzugefügt: %s</string> <string name="contact_added_toast">Kontakt hinzugefügt: %s</string>
<string name="contact_already_exists">Kontakt %s existiert bereits</string> <string name="contact_already_exists">Kontakt %s existiert bereits</string>
<string name="contact_already_exists_general">Kontakt existiert bereits</string>
<string name="qr_code_invalid">Der QR-Code ist ungültig</string> <string name="qr_code_invalid">Der QR-Code ist ungültig</string>
<string name="qr_code_too_old_1">Der QR-Code, den du gescannt hast, kommt von einer älteren Version von Briar.\n\nBitte deinen Kontakt, zur neuesten Version upzudaten, und versuche es erneut.</string> <string name="qr_code_too_old_1">Der QR-Code, den du gescannt hast, kommt von einer älteren Version von Briar.\n\nBitte deinen Kontakt, zur neuesten Version upzudaten, und versuche es erneut.</string>
<string name="qr_code_too_new_1">Der QR-Code, den du gescannt hast, kommt von einer neueren Version.\n\nBitte aktualisiere Briar auf die neueste Version und versuche es erneut.</string> <string name="qr_code_too_new_1">Der QR-Code, den du gescannt hast, kommt von einer neueren Version.\n\nBitte aktualisiere Briar auf die neueste Version und versuche es erneut.</string>
@@ -267,9 +266,9 @@
<string name="pending_contact_requests_snackbar">Es gibt ausstehende Kontaktanfragen</string> <string name="pending_contact_requests_snackbar">Es gibt ausstehende Kontaktanfragen</string>
<string name="pending_contact_requests">Ausstehende Kontaktanfragen</string> <string name="pending_contact_requests">Ausstehende Kontaktanfragen</string>
<string name="no_pending_contacts">Keine ausstehenden Kontakte</string> <string name="no_pending_contacts">Keine ausstehenden Kontakte</string>
<string name="waiting_for_contact_to_come_online">Warte auf Online-Aktivität des Kontakts</string> <string name="waiting_for_contact_to_come_online">Warte auf Online-Aktivität des Kontakts ...</string>
<string name="connecting">Verbinde…</string> <string name="connecting">Verbinde…</string>
<string name="adding_contact">Kontakt hinzufügen</string> <string name="adding_contact">Kontakt hinzufügen...</string>
<string name="adding_contact_failed">Hinzufügen von Kontakt ist fehlgeschlagen</string> <string name="adding_contact_failed">Hinzufügen von Kontakt ist fehlgeschlagen</string>
<string name="dialog_title_remove_pending_contact">Entfernung bestätigen</string> <string name="dialog_title_remove_pending_contact">Entfernung bestätigen</string>
<string name="dialog_message_remove_pending_contact">Dieser Kontakt befindet sich noch beim Hinzufügen. Wenn er jetzt entfernt wird, wird das Hinzufügen abgebrochen.</string> <string name="dialog_message_remove_pending_contact">Dieser Kontakt befindet sich noch beim Hinzufügen. Wenn er jetzt entfernt wird, wird das Hinzufügen abgebrochen.</string>
@@ -488,9 +487,8 @@
<string name="blogs_rss_feeds_import">RSS-Feed importieren</string> <string name="blogs_rss_feeds_import">RSS-Feed importieren</string>
<string name="blogs_rss_feeds_import_button">Importieren</string> <string name="blogs_rss_feeds_import_button">Importieren</string>
<string name="blogs_rss_feeds_import_hint">URL des RSS-Feeds eingeben</string> <string name="blogs_rss_feeds_import_hint">URL des RSS-Feeds eingeben</string>
<string name="blogs_rss_feeds_import_progress">RSS-Feed wird importiert…</string>
<string name="blogs_rss_feeds_import_error">Es tut uns Leid! Es gab einen Fehler beim Importieren deines Feeds.</string> <string name="blogs_rss_feeds_import_error">Es tut uns Leid! Es gab einen Fehler beim Importieren deines Feeds.</string>
<string name="blogs_rss_feeds_import_title">Feed aus Datei importieren</string> <string name="blogs_rss_feeds_import_exists">Dieser Feed ist bereits importiert.</string>
<string name="blogs_rss_feeds">RSS-Feeds</string> <string name="blogs_rss_feeds">RSS-Feeds</string>
<string name="blogs_rss_feeds_manage_imported">Importiert:</string> <string name="blogs_rss_feeds_manage_imported">Importiert:</string>
<string name="blogs_rss_feeds_manage_author">Autor:</string> <string name="blogs_rss_feeds_manage_author">Autor:</string>
@@ -731,7 +729,7 @@
<string name="dev_report_saved">Der Bericht wurde gespeichert. Er wird verschickt, wenn du dich das nächste Mal bei Briar anmeldest.</string> <string name="dev_report_saved">Der Bericht wurde gespeichert. Er wird verschickt, wenn du dich das nächste Mal bei Briar anmeldest.</string>
<string name="dev_report_error">Fehler: Senden des Reports fehlgeschlagen</string> <string name="dev_report_error">Fehler: Senden des Reports fehlgeschlagen</string>
<!--Sign Out--> <!--Sign Out-->
<string name="progress_title_logout">Von Briar abmelden</string> <string name="progress_title_logout">Von Briar abmelden...</string>
<!--Screen Filters & Tapjacking--> <!--Screen Filters & Tapjacking-->
<string name="screen_filter_title">Bildschirmüberlagerung erkannt</string> <string name="screen_filter_title">Bildschirmüberlagerung erkannt</string>
<string name="screen_filter_body">Eine andere App überlagert Briar. Um deine Sicherheit zu gewährleisten, reagiert Briar in diesem Fall nicht auf deine Eingaben.\n\nDie folgenden Apps könnten überlagern:\n\n%1$s</string> <string name="screen_filter_body">Eine andere App überlagert Briar. Um deine Sicherheit zu gewährleisten, reagiert Briar in diesem Fall nicht auf deine Eingaben.\n\nDie folgenden Apps könnten überlagern:\n\n%1$s</string>

View File

@@ -443,7 +443,6 @@
<string name="forum_declined_toast">La invitación ha sido rechazada</string> <string name="forum_declined_toast">La invitación ha sido rechazada</string>
<string name="shared_by_format">Compartido por %s</string> <string name="shared_by_format">Compartido por %s</string>
<string name="forum_invitation_already_sharing">Ya se está compartiendo</string> <string name="forum_invitation_already_sharing">Ya se está compartiendo</string>
<string name="forum_invitation_already_invited">Invitación ya enviada</string>
<string name="forum_invitation_response_accepted_sent">Aceptaste la invitación al foro de %s.</string> <string name="forum_invitation_response_accepted_sent">Aceptaste la invitación al foro de %s.</string>
<string name="forum_invitation_response_declined_sent">Rechazaste la invitación al foro de %s.</string> <string name="forum_invitation_response_declined_sent">Rechazaste la invitación al foro de %s.</string>
<string name="forum_invitation_response_declined_auto">La invitación al foro de %s fue automáticamente rechazada.</string> <string name="forum_invitation_response_declined_auto">La invitación al foro de %s fue automáticamente rechazada.</string>
@@ -496,6 +495,7 @@
<string name="blogs_rss_feeds_import_button">Importar</string> <string name="blogs_rss_feeds_import_button">Importar</string>
<string name="blogs_rss_feeds_import_hint">Introduce la URL del canal RSS</string> <string name="blogs_rss_feeds_import_hint">Introduce la URL del canal RSS</string>
<string name="blogs_rss_feeds_import_error">¡Lo sentimos! Hubo un error importando tu canal.</string> <string name="blogs_rss_feeds_import_error">¡Lo sentimos! Hubo un error importando tu canal.</string>
<string name="blogs_rss_feeds_import_exists">Ese canal ya está importado.</string>
<string name="blogs_rss_feeds">Canales RSS</string> <string name="blogs_rss_feeds">Canales RSS</string>
<string name="blogs_rss_feeds_manage_imported">Importado:</string> <string name="blogs_rss_feeds_manage_imported">Importado:</string>
<string name="blogs_rss_feeds_manage_author">Autor:</string> <string name="blogs_rss_feeds_manage_author">Autor:</string>

View File

@@ -510,6 +510,7 @@
<string name="blogs_rss_feeds_import_button">وارد کردن</string> <string name="blogs_rss_feeds_import_button">وارد کردن</string>
<string name="blogs_rss_feeds_import_hint">آدرس خوراک RSS را وارد کنید</string> <string name="blogs_rss_feeds_import_hint">آدرس خوراک RSS را وارد کنید</string>
<string name="blogs_rss_feeds_import_error">متاسفیم! وارد کردن خوراک شما با خطا مواجه شده است.</string> <string name="blogs_rss_feeds_import_error">متاسفیم! وارد کردن خوراک شما با خطا مواجه شده است.</string>
<string name="blogs_rss_feeds_import_exists">این خوراک وارد شده است.</string>
<string name="blogs_rss_feeds">خوراک های RSS</string> <string name="blogs_rss_feeds">خوراک های RSS</string>
<string name="blogs_rss_feeds_manage_imported">وارد شده:</string> <string name="blogs_rss_feeds_manage_imported">وارد شده:</string>
<string name="blogs_rss_feeds_manage_author">نویسنده:</string> <string name="blogs_rss_feeds_manage_author">نویسنده:</string>

View File

@@ -482,6 +482,7 @@
<string name="blogs_rss_feeds_import_button">Importer</string> <string name="blogs_rss_feeds_import_button">Importer</string>
<string name="blogs_rss_feeds_import_hint">Saisir lURL du fil RSS</string> <string name="blogs_rss_feeds_import_hint">Saisir lURL du fil RSS</string>
<string name="blogs_rss_feeds_import_error">Nous sommes désolés! Une erreur est survenue lors de limportation de votre fil.</string> <string name="blogs_rss_feeds_import_error">Nous sommes désolés! Une erreur est survenue lors de limportation de votre fil.</string>
<string name="blogs_rss_feeds_import_exists">Ce fil est déjà importé.</string>
<string name="blogs_rss_feeds">Fils RSS</string> <string name="blogs_rss_feeds">Fils RSS</string>
<string name="blogs_rss_feeds_manage_imported">Importés :</string> <string name="blogs_rss_feeds_manage_imported">Importés :</string>
<string name="blogs_rss_feeds_manage_author">Auteur :</string> <string name="blogs_rss_feeds_manage_author">Auteur :</string>

View File

@@ -466,6 +466,7 @@
<string name="blogs_rss_feeds_import_button">Flytja inn</string> <string name="blogs_rss_feeds_import_button">Flytja inn</string>
<string name="blogs_rss_feeds_import_hint">Settu inn slóðina á RSS-streymið</string> <string name="blogs_rss_feeds_import_hint">Settu inn slóðina á RSS-streymið</string>
<string name="blogs_rss_feeds_import_error">Því miður! Það kom upp villa við að flytja inn streymið.</string> <string name="blogs_rss_feeds_import_error">Því miður! Það kom upp villa við að flytja inn streymið.</string>
<string name="blogs_rss_feeds_import_exists">Þegar er búið að flytja inn þetta streymi.</string>
<string name="blogs_rss_feeds">RSS-fréttastreymi</string> <string name="blogs_rss_feeds">RSS-fréttastreymi</string>
<string name="blogs_rss_feeds_manage_imported">Flutt inn:</string> <string name="blogs_rss_feeds_manage_imported">Flutt inn:</string>
<string name="blogs_rss_feeds_manage_author">Höfundur:</string> <string name="blogs_rss_feeds_manage_author">Höfundur:</string>

View File

@@ -501,9 +501,8 @@
<string name="blogs_rss_feeds_import">Importa RSS Feed</string> <string name="blogs_rss_feeds_import">Importa RSS Feed</string>
<string name="blogs_rss_feeds_import_button">Importa</string> <string name="blogs_rss_feeds_import_button">Importa</string>
<string name="blogs_rss_feeds_import_hint">Inserire l\'URL dell\'RSS feed</string> <string name="blogs_rss_feeds_import_hint">Inserire l\'URL dell\'RSS feed</string>
<string name="blogs_rss_feeds_import_progress">Importazione RSS Feed…</string>
<string name="blogs_rss_feeds_import_error">Ci dispiace! C\'è stato un errore nell\'importazione del tuo feed.</string> <string name="blogs_rss_feeds_import_error">Ci dispiace! C\'è stato un errore nell\'importazione del tuo feed.</string>
<string name="blogs_rss_feeds_import_title">Importa feed da file</string> <string name="blogs_rss_feeds_import_exists">Quel flusso è già importato.</string>
<string name="blogs_rss_feeds">Flussi RSS</string> <string name="blogs_rss_feeds">Flussi RSS</string>
<string name="blogs_rss_feeds_manage_imported">Importato:</string> <string name="blogs_rss_feeds_manage_imported">Importato:</string>
<string name="blogs_rss_feeds_manage_author">Autore:</string> <string name="blogs_rss_feeds_manage_author">Autore:</string>

View File

@@ -1,13 +1,13 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<!--Setup--> <!--Setup-->
<string name="setup_title">Briarへようこそ</string> <string name="setup_title">Briar へようこそ</string>
<string name="setup_name_explanation">あなたのニックネームは、常に、あなたが投稿するコンテンツとともに表示されます。プロフィール作成後、編集はできません。</string> <string name="setup_name_explanation">あなたのニックネームは、常に、あなたが投稿するコンテンツとともに表示されます。プロフィール作成後、編集はできません。</string>
<string name="setup_next">次へ</string> <string name="setup_next">次へ</string>
<string name="setup_password_intro">パスワードを選択</string> <string name="setup_password_intro">パスワードを選択</string>
<string name="setup_password_explanation">Briarのアカウント情報はクラウドではなく、暗号化された端末に保存されます。アプリのアンインストールやパスワードを紛失した場合、アカウントへのアクセスとデータを回復する手段はありません。\n\n推測するのが難しい、長いパスワードを設定してください。ランダムな単語やランダムな10文字と数字と記号を組み合わせたものなどです。</string> <string name="setup_password_explanation">Briar のアカウント情報はクラウドではなく、暗号化された端末に保存されます。アプリのアンインストールやパスワードを紛失した場合、アカウントへのアクセスとデータを回復する手段はありません。\n\n推測するのが難しい、長いパスワードを設定してください。ランダムな単語やランダムな10文字と数字と記号を組み合わせたものなどです。</string>
<string name="dnkm_doze_intro">メッセージを受信するために、Briarはバックグラウンドで接続を維持する必要があります。</string> <string name="dnkm_doze_intro">メッセージを受信するために、Briar はバックグラウンドで接続を維持する必要があります。</string>
<string name="dnkm_doze_explanation">メッセージを受信するために、Briarはバックグラウンドで接続を維持する必要があります。 Briarが接続を維持できるように、バッテリーの最適化を無効にしてください。</string> <string name="dnkm_doze_explanation">メッセージを受信するために、Briar はバックグラウンドで接続を維持する必要があります。 Briar が接続を維持できるように、バッテリーの最適化を無効にしてください。</string>
<string name="choose_nickname">ニックネームを入力</string> <string name="choose_nickname">ニックネームを入力</string>
<string name="choose_password">パスワードを入力</string> <string name="choose_password">パスワードを入力</string>
<string name="confirm_password">確認のため再度パスワードを入力</string> <string name="confirm_password">確認のため再度パスワードを入力</string>
@@ -17,42 +17,42 @@
<string name="create_account_button">アカウントを作成</string> <string name="create_account_button">アカウントを作成</string>
<string name="more_info">詳細情報</string> <string name="more_info">詳細情報</string>
<string name="don_t_ask_again">次からは尋ねない</string> <string name="don_t_ask_again">次からは尋ねない</string>
<string name="dnkm_huawei_protected_text">下のボタンをタップして、「保護されたアプリ」画面で Briarが保護されていることを確認してください。</string> <string name="dnkm_huawei_protected_text">下のボタンをタップして、「保護されたアプリ」画面で Briar が保護されていることを確認してください。</string>
<string name="dnkm_huawei_protected_button">Briarを保護する</string> <string name="dnkm_huawei_protected_button">Briar を保護する</string>
<string name="dnkm_huawei_protected_help">Briarが保護されたアプリのリストに追加されていないと、Briarはバックグラウンドで実行することができません。</string> <string name="dnkm_huawei_protected_help">Briar が保護されたアプリのリストに追加されていないと、Briar はバックグラウンドで実行することができません。</string>
<string name="dnkm_huawei_app_launch_text">下のボタンをタップして「アプリの起動」画面を開き、Briarが「手動で管理する」に設定されていることを確認してください。</string> <string name="dnkm_huawei_app_launch_text">下のボタンをタップして「アプリの起動」画面を開き、Briar が「手動で管理する」に設定されていることを確認してください。</string>
<string name="dnkm_huawei_app_launch_help">「アプリ起動」画面で Briarを「手動で管理する」に設定していないと、バックグラウンドで動作させることができません。</string> <string name="dnkm_huawei_app_launch_help">「アプリ起動」画面で Briar を「手動で管理する」に設定していないと、バックグラウンドで動作させることができません。</string>
<string name="dnkm_xiaomi_text">バックグラウンドで実行するには、Briarを最近のアプリのリストにロックする必要があります。</string> <string name="dnkm_xiaomi_text">バックグラウンドで実行するには、Briar を最近のアプリのリストにロックする必要があります。</string>
<string name="dnkm_xiaomi_button">Briarを保護する</string> <string name="dnkm_xiaomi_button">Briar を保護する</string>
<string name="dnkm_xiaomi_help">Briarが最近のアプリのリストにロックされていないと、バックグラウンドで実行することができません。</string> <string name="dnkm_xiaomi_help">Briar が最近のアプリのリストにロックされていないと、バックグラウンドで実行することができません。</string>
<string name="dnkm_xiaomi_dialog_body_old">1. 最近使ったアプリのリスト(アプリスイッチャーともいう)を開いて下さい。\n\n2. Briarの画像を下にスワイプすると、南京錠のアイコンが表示されます。\n\n3. ロックされていない場合は、タップしてロックします。</string> <string name="dnkm_xiaomi_dialog_body_old">1. 最近使ったアプリのリスト(アプリスイッチャーともいう)を開いて下さい。\n\n2. Briar の画像を下にスワイプすると、南京錠のアイコンが表示されます。\n\n3. ロックされていない場合は、タップしてロックします。</string>
<string name="dnkm_warning_dozed_1">Briarはバックグラウンドで実行できませんでした</string> <string name="dnkm_warning_dozed_1">Briarはバックグラウンドで実行することができませんでした</string>
<!--Login--> <!--Login-->
<string name="enter_password">パスワード</string> <string name="enter_password">パスワード</string>
<string name="try_again">パスワードが間違っています。もう一度入力してください。</string> <string name="try_again">パスワードが間違っています。もう一度入力してください。</string>
<string name="dialog_title_cannot_check_password">パスワードを確認できません</string> <string name="dialog_title_cannot_check_password">パスワードを確認できません</string>
<string name="dialog_message_cannot_check_password">Briarがパスワードを確認することができませんでした。この問題を解決するには、端末の再起動を試してください。</string> <string name="dialog_message_cannot_check_password">Briar がパスワードを確認することができませんでした。この問題を解決するには、端末の再起動を試してください。</string>
<string name="sign_in_button">サインイン</string> <string name="sign_in_button">サインイン</string>
<string name="forgotten_password">パスワードを忘れました</string> <string name="forgotten_password">パスワードを忘れました</string>
<string name="dialog_title_lost_password">パスワードを紛失</string> <string name="dialog_title_lost_password">パスワードを紛失</string>
<string name="dialog_message_lost_password">Briarアカウントはクラウド上ではなく、暗号化さた上であなたの端末に保存さています。したがって、Briarはパスワードをリセットできません。アカウントを削除して、はじめからやり直しますか\n\n注意あなたのID、連絡先、メッセージは永久に失われます。</string> <string name="dialog_message_lost_password">Briar アカウントはクラウド上ではなく、暗号化さた上であなたの端末に保存さています。したがって、Briar はパスワードをリセットできません。アカウントを削除して、はじめからやり直しますか?\n\n注意あなたのID、連絡先、メッセージは永久に失われます。</string>
<string name="startup_failed_activity_title">Briarの起動に失敗</string> <string name="startup_failed_activity_title">Briar の起動に失敗しました</string>
<string name="startup_failed_clock_error">お使いの端末の時計が正しくないため、Briarは起動できませんでした。\n\n端末の時計を正しい時刻に設定してから、もう一度試してください。</string> <string name="startup_failed_clock_error">お使いの端末の時計が正しくないため、Briar は起動できませんでした。\n\n端末の時計を正しい時刻に設定してから、もう一度試してください。</string>
<string name="startup_failed_db_error">Briarは、あなたのアカウント、連絡先、メッセージを含むデータベースを開くことができませんでした。\n\nアプリを最新版にアップグレードしてもう一度お試しいただくか、パスワード入力画面で「パスワードを忘れました」を選択して新しいアカウントを設定してください。</string> <string name="startup_failed_db_error">Briar は、あなたのアカウント、連絡先、メッセージを含むデータベースを開くことができませんでした。\n\nアプリを最新版にアップグレードしてもう一度お試しいただくか、パスワード入力画面で「パスワードを忘れました」を選択して新しいアカウントを設定してください。</string>
<string name="startup_failed_data_too_old_error">あなたのアカウントは古いバージョンのアプリで作成されたもので、このバージョンでは開くことができません。\n\n古いバージョンを再インストールするか、パスワード入力画面で\'パスワードを忘れました\'を選択して新しいアカウントを設定する必要があります。</string> <string name="startup_failed_data_too_old_error">あなたのアカウントは古いバージョンのアプリで作成されたもので、このバージョンでは開くことができません。\n\n古いバージョンを再インストールするか、パスワード入力画面で\'パスワードを忘れました\'を選択して新しいアカウントを設定する必要があります。</string>
<string name="startup_failed_data_too_new_error">あなたのアカウントは、このアプリの新しいバージョンで作成されたもので、このバージョンでは開くことができません。\n\n最新版にアップグレードしてから、もう一度試してください。</string> <string name="startup_failed_data_too_new_error">あなたのアカウントは、このアプリの新しいバージョンで作成されたもので、このバージョンでは開くことができません。\n\n最新版にアップグレードしてから、もう一度試してください。</string>
<string name="startup_failed_service_error">Briarは要求されたコンポーネントを起動できませんでした。\n\nアプリの最新版にアップグレードしてから、もう一度試してください。</string> <string name="startup_failed_service_error">Briar は、必要なコンポーネントを起動できませんでした。\n\nアプリの最新版にアップグレードしてから、もう一度試してください。</string>
<plurals name="expiry_warning"> <plurals name="expiry_warning">
<item quantity="other">これは、Briarのテストバージョンです。 アカウントはあと%d日で期限切れになり、更新できません。</item> <item quantity="other">これは、Briar のテストバージョンです。 アカウントはあと%d日で期限切れになり、更新できません。</item>
</plurals> </plurals>
<plurals name="old_android_expiry_warning"> <plurals name="old_android_expiry_warning">
<item quantity="other">Android 4はサポートされなくなりました。Briarは(%d日後に)%s上での動作を停止します。新しい端末に Briarをインストールして、新しいアカウントを作成してください。</item> <item quantity="other">Android 4はサポートされなくなりました。Briar は(%d日後に)%s上での動作を停止します。新しい端末に Briar をインストールして、新しいアカウントを作成してください。</item>
</plurals> </plurals>
<string name="expiry_date_reached">このソフトウェアの有効期限が切れました。テストに参加してくださりありがとうございます!</string> <string name="expiry_date_reached">このソフトウェアの有効期限が切れました。テストに参加してくださりありがとうございます!</string>
<string name="download_briar">Briarの使用を続けるには、最新リリースをダウンロードしてください。</string> <string name="download_briar">Briarの使用を続けるには、最新リリースをダウンロードしてください。</string>
<string name="create_new_account">新しいアカウントを作成する必要があります。同じニックネームも使用できます。</string> <string name="create_new_account">新しいアカウントを作成する必要があります。同じニックネームも使用できます。</string>
<string name="download_briar_button">最新リリースをダウンロード</string> <string name="download_briar_button">最新リリースをダウンロード</string>
<string name="old_android_expiry_date_reached">BriarAndroid 4では動作しなくなりました。\n新しい端末にBriarをインストールしてください。</string> <string name="old_android_expiry_date_reached">BriarAndroid 4 では動作しなくなりました。\n新しい端末にBriarをインストールしてください。</string>
<string name="old_android_delete_account">下のボタンをタップして、この端末からあなたのアカウントを削除できます。</string> <string name="old_android_delete_account">下のボタンをタップして、この端末からあなたのアカウントを削除できます。</string>
<string name="delete_account_button">アカウントを削除</string> <string name="delete_account_button">アカウントを削除</string>
<string name="startup_open_database">データベースの復号化中…</string> <string name="startup_open_database">データベースの復号化中…</string>
@@ -69,36 +69,36 @@
<string name="lock_button">アプリをロック</string> <string name="lock_button">アプリをロック</string>
<string name="settings_button">設定</string> <string name="settings_button">設定</string>
<string name="sign_out_button">サインアウト</string> <string name="sign_out_button">サインアウト</string>
<string name="transports_onboarding_text">ここにタップすると、Briarがあなたの連絡先に接続する方法を制御できます。</string> <string name="transports_onboarding_text">ここにタップすると、Briar があなたの連絡先に接続する方法を制御できます。</string>
<!--Transports: Tor--> <!--Transports: Tor-->
<string name="transport_tor">インターネット</string> <string name="transport_tor">インターネット</string>
<string name="tor_device_status_online_wifi">電話機はWi-Fiでインターネットにアクセスできます</string> <string name="tor_device_status_online_wifi">電話機はWi-Fiでインターネットにアクセスできます</string>
<string name="tor_device_status_online_mobile">電話機はモバイル データでインターネットにアクセスできます</string> <string name="tor_device_status_online_mobile">電話機はモバイル データでインターネットにアクセスできます</string>
<string name="tor_device_status_offline">電話機がインターネットに接続できません</string> <string name="tor_device_status_offline">電話機がインターネットに接続できません</string>
<string name="tor_plugin_status_enabling">Briarはインターネットに接続中です…</string> <string name="tor_plugin_status_enabling">Briar はインターネットに接続中です…</string>
<string name="tor_plugin_status_active">Briarはインターネットに接続されました</string> <string name="tor_plugin_status_active">Briar はインターネットに接続されました</string>
<string name="tor_plugin_status_inactive">Briarはインターネットに接続できません</string> <string name="tor_plugin_status_inactive">Briar はインターネットに接続できません</string>
<string name="tor_plugin_status_disabled">Briarはインターネットを使用しないように設定されています</string> <string name="tor_plugin_status_disabled">Briar はインターネットを使用しないように設定されています</string>
<string name="tor_plugin_status_disabled_mobile_data">Briarはモバイルデータを使用しないように設定されています</string> <string name="tor_plugin_status_disabled_mobile_data">Briar はモバイルデータを使用しないように設定されています</string>
<string name="tor_plugin_status_disabled_battery">Briarはバッテリー駆動時にインターネットを使用しないように設定されています</string> <string name="tor_plugin_status_disabled_battery">Briar はバッテリー駆動時にインターネットを使用しないように設定されています</string>
<string name="tor_plugin_status_disabled_country_blocked">Briarはこの国でインターネットを使わないように設定されています</string> <string name="tor_plugin_status_disabled_country_blocked">Briar はこの国でインターネットを使わないように設定されています</string>
<!--Transports: Wi-Fi--> <!--Transports: Wi-Fi-->
<string name="transport_lan">Wi-Fi</string> <string name="transport_lan">Wi-Fi</string>
<string name="transport_lan_long">同じ Wi-Fi ネットワーク</string> <string name="transport_lan_long">同じ Wi-Fi ネットワーク</string>
<string name="lan_device_status_on">電話機は Wi-Fi に接続されました</string> <string name="lan_device_status_on">電話機は Wi-Fi に接続されました</string>
<string name="lan_device_status_off">電話機はWi-Fiに接続されていません</string> <string name="lan_device_status_off">電話機はWi-Fiに接続されていません</string>
<string name="lan_plugin_status_enabling">BriarWi-Fiネットワークに接続中です…</string> <string name="lan_plugin_status_enabling">BriarWi-Fi ネットワークに接続中です…</string>
<string name="lan_plugin_status_active">BriarWi-Fiネットワークに接続されました</string> <string name="lan_plugin_status_active">BriarWi-Fi ネットワークに接続されました</string>
<string name="lan_plugin_status_inactive">BriarWi-Fiネットワークに接続できません</string> <string name="lan_plugin_status_inactive">BriarWi-Fi ネットワークに接続できません</string>
<string name="lan_plugin_status_disabled">BriarWi-Fiネットワークを使用しないように設定されています</string> <string name="lan_plugin_status_disabled">BriarWi-Fi ネットワークを使用しないように設定されています</string>
<!--Transports: Bluetooth--> <!--Transports: Bluetooth-->
<string name="transport_bt">Bluetooth</string> <string name="transport_bt">Bluetooth</string>
<string name="bt_device_status_on">携帯電話の Bluetooth はオンになっています</string> <string name="bt_device_status_on">携帯電話の Bluetooth はオンになっています</string>
<string name="bt_device_status_off">携帯電話の Bluetooth はオフにされました</string> <string name="bt_device_status_off">携帯電話の Bluetooth はオフにされました</string>
<string name="bt_plugin_status_enabling">BriarBluetoothに接続中です…</string> <string name="bt_plugin_status_enabling">BriarBluetooth に接続中です…</string>
<string name="bt_plugin_status_active">BriarBluetoothに接続しました</string> <string name="bt_plugin_status_active">BriarBluetooth に接続しました</string>
<string name="bt_plugin_status_inactive">BriarBluetoothに接続できません</string> <string name="bt_plugin_status_inactive">BriarBluetooth に接続できません</string>
<string name="bt_plugin_status_disabled">BriarBluetoothを使用しないように設定されています</string> <string name="bt_plugin_status_disabled">BriarBluetooth を使用しないように設定されています</string>
<!--Notifications--> <!--Notifications-->
<string name="reminder_notification_title">Briarからサインアウト</string> <string name="reminder_notification_title">Briarからサインアウト</string>
<string name="reminder_notification_text">タップして再ログインします。</string> <string name="reminder_notification_text">タップして再ログインします。</string>
@@ -323,7 +323,6 @@
<string name="connect_via_bluetooth_intro">Bluetooth接続が自動的に行われない場合は、この画面を使って手動で接続することができます。\n\nこの機能を利用するには、あなたの連絡先が近くにある必要があります。\n\nあなたと連絡先が同時に\"開始\"を押してください。</string> <string name="connect_via_bluetooth_intro">Bluetooth接続が自動的に行われない場合は、この画面を使って手動で接続することができます。\n\nこの機能を利用するには、あなたの連絡先が近くにある必要があります。\n\nあなたと連絡先が同時に\"開始\"を押してください。</string>
<string name="connect_via_bluetooth_already_discovering">既にBluetooth経由での接続を試行中です。すぐに再試行してください。</string> <string name="connect_via_bluetooth_already_discovering">既にBluetooth経由での接続を試行中です。すぐに再試行してください。</string>
<string name="connect_via_bluetooth_no_location_permission">位置情報の権限なくして続行不可能</string> <string name="connect_via_bluetooth_no_location_permission">位置情報の権限なくして続行不可能</string>
<string name="connect_via_bluetooth_no_bluetooth_permission">付近の端末の権限なくして続行不可能</string>
<string name="connect_via_bluetooth_start">Bluetooth経由で接続中…</string> <string name="connect_via_bluetooth_start">Bluetooth経由で接続中…</string>
<string name="connect_via_bluetooth_success">Bluetooth経由で接続に成功</string> <string name="connect_via_bluetooth_success">Bluetooth経由で接続に成功</string>
<string name="connect_via_bluetooth_error">Bluetooth経由で接続不可能。</string> <string name="connect_via_bluetooth_error">Bluetooth経由で接続不可能。</string>
@@ -349,9 +348,9 @@
<string name="groups_member_created">%sがグループを作成しました</string> <string name="groups_member_created">%sがグループを作成しました</string>
<string name="groups_member_joined_you">グループに参加しました</string> <string name="groups_member_joined_you">グループに参加しました</string>
<string name="groups_member_joined">%sがグループに参加しました</string> <string name="groups_member_joined">%sがグループに参加しました</string>
<string name="groups_leave">グループを脱退</string> <string name="groups_leave">グループをやめる</string>
<string name="groups_leave_dialog_title">グループをやめる確認</string> <string name="groups_leave_dialog_title">グループをやめる確認</string>
<string name="groups_leave_dialog_message">このグループを脱退してもよろしいですか?</string> <string name="groups_leave_dialog_message">このグループをやめてもよろしいですか?</string>
<string name="groups_dissolve">グループを削除</string> <string name="groups_dissolve">グループを削除</string>
<string name="groups_dissolve_dialog_title">グループの削除の確認</string> <string name="groups_dissolve_dialog_title">グループの削除の確認</string>
<string name="groups_dissolve_dialog_message">このグループを削除してもよろしいですか?\n\nグループを削除すると、他のすべてのメンバーは会話を続けることができなくなり、最新のメッセージは受信できなくなります。</string> <string name="groups_dissolve_dialog_message">このグループを削除してもよろしいですか?\n\nグループを削除すると、他のすべてのメンバーは会話を続けることができなくなり、最新のメッセージは受信できなくなります。</string>
@@ -395,10 +394,10 @@
<string name="forum_new_message_hint">新しい投稿</string> <string name="forum_new_message_hint">新しい投稿</string>
<string name="forum_message_reply_hint">新しい返信</string> <string name="forum_message_reply_hint">新しい返信</string>
<string name="btn_reply">返信</string> <string name="btn_reply">返信</string>
<string name="forum_leave">フォーラムを脱退</string> <string name="forum_leave">フォーラムをやめる</string>
<string name="dialog_title_leave_forum">フォーラムをやめる確認</string> <string name="dialog_title_leave_forum">フォーラムをやめる確認</string>
<string name="dialog_message_leave_forum">このフォーラムを脱退してもよろしいですか?\n\nこのフォーラムで共有した連絡先は更新の受信を停止します。</string> <string name="dialog_message_leave_forum">このフォーラムをやめてもよろしいですか?\n\nこのフォーラムで共有した連絡先は更新の受信を停止します。</string>
<string name="dialog_button_leave">脱退</string> <string name="dialog_button_leave">脱退する</string>
<string name="forum_left_toast">フォーラムをやめました</string> <string name="forum_left_toast">フォーラムをやめました</string>
<!--Forum Sharing--> <!--Forum Sharing-->
<string name="forum_share_button">フォーラムを共有</string> <string name="forum_share_button">フォーラムを共有</string>
@@ -417,10 +416,6 @@
<string name="forum_declined_toast">招待を辞退しました</string> <string name="forum_declined_toast">招待を辞退しました</string>
<string name="shared_by_format">%sによって共有されました。</string> <string name="shared_by_format">%sによって共有されました。</string>
<string name="forum_invitation_already_sharing">既に共有しています</string> <string name="forum_invitation_already_sharing">既に共有しています</string>
<string name="forum_invitation_already_invited">招待は既に送信しました</string>
<string name="forum_invitation_invite_received">招待は既に受信されました</string>
<string name="forum_invitation_not_supported">この連絡先によってサポートされていません</string>
<string name="forum_invitation_error">エラー。これはバグか、そうでなければ、あなたの誤りです</string>
<string name="forum_invitation_response_accepted_sent">%sからのフォーラムへの招待を受け入れました。</string> <string name="forum_invitation_response_accepted_sent">%sからのフォーラムへの招待を受け入れました。</string>
<string name="forum_invitation_response_declined_sent">%sからのフォーラムへの招待を辞退しました。</string> <string name="forum_invitation_response_declined_sent">%sからのフォーラムへの招待を辞退しました。</string>
<string name="forum_invitation_response_declined_auto">%sからのフォーラムへの招待は自動的に辞退されました。</string> <string name="forum_invitation_response_declined_auto">%sからのフォーラムへの招待は自動的に辞退されました。</string>
@@ -470,9 +465,8 @@
<string name="blogs_rss_feeds_import">RSSフィードをインポート</string> <string name="blogs_rss_feeds_import">RSSフィードをインポート</string>
<string name="blogs_rss_feeds_import_button">インポート</string> <string name="blogs_rss_feeds_import_button">インポート</string>
<string name="blogs_rss_feeds_import_hint">RSSフィードのURLを入力してください</string> <string name="blogs_rss_feeds_import_hint">RSSフィードのURLを入力してください</string>
<string name="blogs_rss_feeds_import_progress">RSSフィードをインポート中…</string>
<string name="blogs_rss_feeds_import_error">申し訳ありません! フィードのインポート中にエラーが発生しました。</string> <string name="blogs_rss_feeds_import_error">申し訳ありません! フィードのインポート中にエラーが発生しました。</string>
<string name="blogs_rss_feeds_import_title">ファイルからフィードインポート</string> <string name="blogs_rss_feeds_import_exists">そのフィードは既にインポートされています。</string>
<string name="blogs_rss_feeds">RSSフィード</string> <string name="blogs_rss_feeds">RSSフィード</string>
<string name="blogs_rss_feeds_manage_imported">インポート済み:</string> <string name="blogs_rss_feeds_manage_imported">インポート済み:</string>
<string name="blogs_rss_feeds_manage_author">著者:</string> <string name="blogs_rss_feeds_manage_author">著者:</string>
@@ -579,7 +573,7 @@
<string name="mailbox_setup_title">メールボックスのセットアップ</string> <string name="mailbox_setup_title">メールボックスのセットアップ</string>
<string name="mailbox_setup_intro">メールボックスはあなたがオフラインの間、連絡先があなたにメッセージを送信することを有効にします。メールボックスはあなたがオンラインになるまで、メッセージを受信し保管します。\n <string name="mailbox_setup_intro">メールボックスはあなたがオフラインの間、連絡先があなたにメッセージを送信することを有効にします。メールボックスはあなたがオンラインになるまで、メッセージを受信し保管します。\n
\n予備端末上にBriarのメールボックスアプリをインストールできます。それを電源とWi-Fiに接続し、常時オンラインにしてください。</string> \n予備端末上にBriarのメールボックスアプリをインストールできます。それを電源とWi-Fiに接続し、常時オンラインにしてください。</string>
<string name="mailbox_setup_download">最初に、Google PlayまたはBriarをダウンロードしたどこかで\"BriarMailbox\"を検索して、他の端末上にメールボックスアプリをインストールします。\n <string name="mailbox_setup_download">最初に、Google PlayまたはBriarをダウンロードしたどこかで\"Briar Mailbox\"を検索して、他の端末上にメールボックスアプリをインストールします。\n
\nそして、メールボックスアプリによって表示されるQRコードを読み取って、Briarとあなたのメールボックス結びつけます。</string> \nそして、メールボックスアプリによって表示されるQRコードを読み取って、Briarとあなたのメールボックス結びつけます。</string>
<string name="mailbox_setup_download_link">ダウンロードリンクを共有</string> <string name="mailbox_setup_download_link">ダウンロードリンクを共有</string>
<string name="mailbox_setup_button_scan">メールボックスのQRコードを読み取る</string> <string name="mailbox_setup_button_scan">メールボックスのQRコードを読み取る</string>
@@ -591,15 +585,15 @@
<string name="mailbox_qr_code_too_new">読み取ったQRコードは、新しいバージョンのBriarメールボックスから生じました。\n\nBriarを最新版にアップグレードしてから、もう一度お試しください。</string> <string name="mailbox_qr_code_too_new">読み取ったQRコードは、新しいバージョンのBriarメールボックスから生じました。\n\nBriarを最新版にアップグレードしてから、もう一度お試しください。</string>
<string name="contact_qr_code_for_mailbox">読み取ったQRコードは、Briarの連絡先を追加するためのものです。\n\n連絡先を追加したいならば、連絡先一覧に行き、+アイコンをタップしてください。</string> <string name="contact_qr_code_for_mailbox">読み取ったQRコードは、Briarの連絡先を追加するためのものです。\n\n連絡先を追加したいならば、連絡先一覧に行き、+アイコンをタップしてください。</string>
<string name="mailbox_setup_qr_code_wrong_description">読み取ったQRコードは、Briarメールボックスから生じたものではありません。メールボックス端末上のBriarメールボックスアプリを開き、提示されたQRコードを読み取ってください。</string> <string name="mailbox_setup_qr_code_wrong_description">読み取ったQRコードは、Briarメールボックスから生じたものではありません。メールボックス端末上のBriarメールボックスアプリを開き、提示されたQRコードを読み取ってください。</string>
<string name="mailbox_setup_already_paired_title">メールボックスは既にリンクされています</string> <string name="mailbox_setup_already_paired_title">メールボックスは既に結びつけられています</string>
<string name="mailbox_setup_already_paired_description">あなたの端末上のメールボックスのリンクを解き、再試行してください。</string> <string name="mailbox_setup_already_paired_description">あなたの端末上のメールボックスの結びつけを解き、再試行してください。</string>
<string name="mailbox_setup_io_error_title">接続できません</string> <string name="mailbox_setup_io_error_title">接続できません</string>
<string name="mailbox_setup_io_error_description">双方の端末がインターネットに接続されていることを確かにして、再試行してください。</string> <string name="mailbox_setup_io_error_description">双方の端末がインターネットに接続されていることを確かにして、再試行してください。</string>
<string name="mailbox_setup_assertion_error_title">メールボックスのエラー</string> <string name="mailbox_setup_assertion_error_title">メールボックスのエラー</string>
<string name="mailbox_setup_assertion_error_description">もし問題が続くのであれば、Briarアプリ経由で匿名データ付きのフィードバックを送信してください。</string> <string name="mailbox_setup_assertion_error_description">もし問題が続くのであれば、Briarアプリ経由で匿名データ付きのフィードバックを送信してください。</string>
<string name="mailbox_setup_camera_error_description">カメラにアクセスできません。端末を再起動してから、もう一度試してみてください。</string> <string name="mailbox_setup_camera_error_description">カメラにアクセスできません。端末を再起動してから、もう一度試してみてください。</string>
<string name="mailbox_setup_paired_title">接続済み</string> <string name="mailbox_setup_paired_title">接続済み</string>
<string name="mailbox_setup_paired_description">あなたのメールボックスはBriarとのリンクに成功しています。\n <string name="mailbox_setup_paired_description">あなたのメールボックスはBriarとの結びつけられるのに成功しています。\n
メールボックスを電源とW-Fiに接続して、常時オンラインにしてください。</string> メールボックスを電源とW-Fiに接続して、常時オンラインにしてください。</string>
<string name="tor_offline_title">オフライン</string> <string name="tor_offline_title">オフライン</string>
<string name="tor_offline_description">この端末がオンラインかつインターネットへの接続が許可されていること確かにしてください。\n <string name="tor_offline_description">この端末がオンラインかつインターネットへの接続が許可されていること確かにしてください。\n
@@ -639,7 +633,7 @@
<string name="mailbox_error_wizard_answer1_1">メールボックスの設定方法が表示される</string> <string name="mailbox_error_wizard_answer1_1">メールボックスの設定方法が表示される</string>
<string name="mailbox_error_wizard_answer1_2">QRコードが表示される</string> <string name="mailbox_error_wizard_answer1_2">QRコードが表示される</string>
<string name="mailbox_error_wizard_answer1_3">「メールボックスは実行中」と表示される</string> <string name="mailbox_error_wizard_answer1_3">「メールボックスは実行中」と表示される</string>
<string name="mailbox_error_wizard_answer1_4">端末がオフライン」と表示されます</string> <string name="mailbox_error_wizard_answer1_4">デバイスがオフライン」と表示されます</string>
<string name="mailbox_error_wizard_info1_1_1">以下のボタンでメールボックスのリンクを解除し、メールボックスの端末の指示に従って再度リンクしてください。</string> <string name="mailbox_error_wizard_info1_1_1">以下のボタンでメールボックスのリンクを解除し、メールボックスの端末の指示に従って再度リンクしてください。</string>
<string name="mailbox_error_wizard_info_1_1_2">以下のボタンでメールボックスのリンクを解除し、QRコードを読み取って再度リンクしてください。</string> <string name="mailbox_error_wizard_info_1_1_2">以下のボタンでメールボックスのリンクを解除し、QRコードを読み取って再度リンクしてください。</string>
<string name="mailbox_error_wizard_info1_1_3">以下のボタンを使用して、Briarとメールボックスの間での接続を確認してください。\n\n <string name="mailbox_error_wizard_info1_1_3">以下のボタンを使用して、Briarとメールボックスの間での接続を確認してください。\n\n
@@ -651,7 +645,7 @@
<string name="mailbox_error_wizard_info3">以下のボタンを使用してメールボックスをリンク解除してください。\n\n古いメールボックスをリンク解除した後、いつでも新しいメールボックスをセットアップできます。</string> <string name="mailbox_error_wizard_info3">以下のボタンを使用してメールボックスをリンク解除してください。\n\n古いメールボックスをリンク解除した後、いつでも新しいメールボックスをセットアップできます。</string>
<!--About--> <!--About-->
<string name="about_title">Tor Project について</string> <string name="about_title">Tor Project について</string>
<string name="briar_version">Briarバージョン: %s</string> <string name="briar_version">Briar バージョン: %s</string>
<string name="tor_version">Tor バージョン: %s</string> <string name="tor_version">Tor バージョン: %s</string>
<string name="links">リンク</string> <string name="links">リンク</string>
<string name="briar_website">\u2022 <a href="">ウェブサイト</a></string> <string name="briar_website">\u2022 <a href="">ウェブサイト</a></string>
@@ -783,7 +777,7 @@
<string name="hotspot_manual_site_address">アドレスURL</string> <string name="hotspot_manual_site_address">アドレスURL</string>
<string name="hotspot_qr_site">あなたの電話機はWi-Fiホットスポットを提供しています。ホットスポットに接続された人は、このQRコードを読み取って、Briarをダウンロードできます。</string> <string name="hotspot_qr_site">あなたの電話機はWi-Fiホットスポットを提供しています。ホットスポットに接続された人は、このQRコードを読み取って、Briarをダウンロードできます。</string>
<!--e.g. Download Briar 1.2.20--> <!--e.g. Download Briar 1.2.20-->
<string name="website_download_title_1">Briar%sをダウンロード</string> <string name="website_download_title_1">Briar %sをダウンロード</string>
<string name="website_download_intro_1">近くの誰かが、あなたとBriarを共有しました。</string> <string name="website_download_intro_1">近くの誰かが、あなたとBriarを共有しました。</string>
<string name="website_download_button">Briarをダウンロード</string> <string name="website_download_button">Briarをダウンロード</string>
<string name="website_download_outro">ダウンロードが完了した後に、ダウンロードしたファイルを開いて、インストールしてください。</string> <string name="website_download_outro">ダウンロードが完了した後に、ダウンロードしたファイルを開いて、インストールしてください。</string>

View File

@@ -477,6 +477,7 @@
<string name="blogs_rss_feeds_import_button">იმპორტი</string> <string name="blogs_rss_feeds_import_button">იმპორტი</string>
<string name="blogs_rss_feeds_import_hint">შეიყვანეთ RSS არხის URL</string> <string name="blogs_rss_feeds_import_hint">შეიყვანეთ RSS არხის URL</string>
<string name="blogs_rss_feeds_import_error">ვწუხვართ! არხის იმპორტირებისას შეცდომა წარმოიშვა.</string> <string name="blogs_rss_feeds_import_error">ვწუხვართ! არხის იმპორტირებისას შეცდომა წარმოიშვა.</string>
<string name="blogs_rss_feeds_import_exists">არხი უკვე იმპორტირებულია.</string>
<string name="blogs_rss_feeds">RSS არხები</string> <string name="blogs_rss_feeds">RSS არხები</string>
<string name="blogs_rss_feeds_manage_imported">იმპორტირებული:</string> <string name="blogs_rss_feeds_manage_imported">იმპორტირებული:</string>
<string name="blogs_rss_feeds_manage_author">ავტორი:</string> <string name="blogs_rss_feeds_manage_author">ავტორი:</string>

View File

@@ -247,14 +247,12 @@
<string name="exchanging_contact_details">Apsikeičiama adresato informacija\u2026</string> <string name="exchanging_contact_details">Apsikeičiama adresato informacija\u2026</string>
<string name="contact_added_toast">Adresatas pridėtas: %s</string> <string name="contact_added_toast">Adresatas pridėtas: %s</string>
<string name="contact_already_exists">Adresatas %s jau yra</string> <string name="contact_already_exists">Adresatas %s jau yra</string>
<string name="contact_already_exists_general">Adresatas jau yra</string>
<string name="qr_code_invalid">QR kodas yra neteisingas</string> <string name="qr_code_invalid">QR kodas yra neteisingas</string>
<string name="camera_error">Kameros klaida</string> <string name="camera_error">Kameros klaida</string>
<string name="connecting_to_device">Jungiamasi prie įrenginio\u2026</string> <string name="connecting_to_device">Jungiamasi prie įrenginio\u2026</string>
<string name="authenticating_with_device">Tapatybės nustatymas su įrenginiu\u2026</string> <string name="authenticating_with_device">Tapatybės nustatymas su įrenginiu\u2026</string>
<string name="connection_error_title">Nepavyko prisijungti prie jūsų adresato</string> <string name="connection_error_title">Nepavyko prisijungti prie jūsų adresato</string>
<string name="connection_error_feedback">Jei ši problema išlieka, <a href="feedback">atsiųskite mums atsiliepimą</a>, kad padėtumėte mums patobulinti programėlę.</string> <string name="connection_error_feedback">Jei ši problema išlieka, <a href="feedback">atsiųskite mums atsiliepimą</a>, kad padėtumėte mums patobulinti programėlę.</string>
<string name="info_both_must_scan">Jūs abu privalote nuskenuoti vienas kito QR kodus</string>
<!--Adding Contacts Remotely--> <!--Adding Contacts Remotely-->
<string name="add_contact_remotely_title_case">Pridėti adresatą per atstumą</string> <string name="add_contact_remotely_title_case">Pridėti adresatą per atstumą</string>
<string name="add_contact_nearby_title">Pridėti šalia esantį adresatą</string> <string name="add_contact_nearby_title">Pridėti šalia esantį adresatą</string>
@@ -268,7 +266,7 @@
<string name="send_link_title">Apsikeiskite nuorodomis</string> <string name="send_link_title">Apsikeiskite nuorodomis</string>
<string name="add_contact_choose_nickname">Pasirinkite slapyvardį</string> <string name="add_contact_choose_nickname">Pasirinkite slapyvardį</string>
<string name="add_contact_choose_a_nickname">Įveskite slapyvardį</string> <string name="add_contact_choose_a_nickname">Įveskite slapyvardį</string>
<string name="nickname_intro">Suteikite adresatui slapyvardį. Slapyvardį matysite tik jūs.</string> <string name="nickname_intro">Suteikite savo adresatui slapyvardį. Slapyvardį matysite tik jūs.</string>
<string name="your_link">Perduokite šią nuorodą adresatui, kurį norite pridėti</string> <string name="your_link">Perduokite šią nuorodą adresatui, kurį norite pridėti</string>
<string name="link_clip_label">Briar nuoroda</string> <string name="link_clip_label">Briar nuoroda</string>
<string name="link_copied_toast">Nuoroda nukopijuota</string> <string name="link_copied_toast">Nuoroda nukopijuota</string>
@@ -314,12 +312,7 @@
<string name="different_person_button">Kitas asmuo</string> <string name="different_person_button">Kitas asmuo</string>
<string name="duplicate_link_dialog_text_3">%1$s ir %2$s išsiuntė jums tą pačią nuorodą.\n\nGali būti, kad vienas iš šių asmenų bando sužinoti kas yra jūsų adresatų sąraše.\n\nNesakykite šiems asmenims, kad gavote tokią pačią nuorodą iš kito asmens.</string> <string name="duplicate_link_dialog_text_3">%1$s ir %2$s išsiuntė jums tą pačią nuorodą.\n\nGali būti, kad vienas iš šių asmenų bando sužinoti kas yra jūsų adresatų sąraše.\n\nNesakykite šiems asmenims, kad gavote tokią pačią nuorodą iš kito asmens.</string>
<string name="pending_contact_updated_toast">Laukiantis adresatas atnaujintas</string> <string name="pending_contact_updated_toast">Laukiantis adresatas atnaujintas</string>
<string name="info_both_must_enter_links">Jūs abu privalote pridėti vienas kito nuorodas</string>
<!--Peer trust levels--> <!--Peer trust levels-->
<string name="peer_trust_level_unverified">Nepatvirtintas adresatas</string>
<string name="peer_trust_level_verified">Patvirtintas adresatas</string>
<string name="peer_trust_level_ourselves"></string>
<string name="peer_trust_level_stranger">Nepažįstamasis</string>
<!--Introductions--> <!--Introductions-->
<string name="introduction_onboarding_title">Supažindinkite savo adresatus</string> <string name="introduction_onboarding_title">Supažindinkite savo adresatus</string>
<string name="introduction_menu_item">Supažindinti</string> <string name="introduction_menu_item">Supažindinti</string>
@@ -449,9 +442,6 @@
<string name="forum_declined_toast">Pakvietimas atmestas</string> <string name="forum_declined_toast">Pakvietimas atmestas</string>
<string name="shared_by_format">Bendrina %s</string> <string name="shared_by_format">Bendrina %s</string>
<string name="forum_invitation_already_sharing">Jau bendrinama</string> <string name="forum_invitation_already_sharing">Jau bendrinama</string>
<string name="forum_invitation_already_invited">Pakvietimas jau išsiųstas</string>
<string name="forum_invitation_invite_received">Pakvietimas jau gautas</string>
<string name="forum_invitation_error">Klaida. Tai yra triktis ir ne jūsų kaltė</string>
<string name="forum_invitation_response_accepted_sent">Jūs priėmėte pakvietimą į forumą iš %s.</string> <string name="forum_invitation_response_accepted_sent">Jūs priėmėte pakvietimą į forumą iš %s.</string>
<string name="forum_invitation_response_declined_sent">Jūs atmetėte pakvietimą į forumą iš %s.</string> <string name="forum_invitation_response_declined_sent">Jūs atmetėte pakvietimą į forumą iš %s.</string>
<string name="forum_invitation_response_declined_auto">Pakvietimas į forumą nuo %s buvo automatiškai atmestas.</string> <string name="forum_invitation_response_declined_auto">Pakvietimas į forumą nuo %s buvo automatiškai atmestas.</string>
@@ -504,9 +494,8 @@
<string name="blogs_rss_feeds_import">Importuoti RSS kanalą</string> <string name="blogs_rss_feeds_import">Importuoti RSS kanalą</string>
<string name="blogs_rss_feeds_import_button">Importuoti</string> <string name="blogs_rss_feeds_import_button">Importuoti</string>
<string name="blogs_rss_feeds_import_hint">Įveskite RSS kanalo URL</string> <string name="blogs_rss_feeds_import_hint">Įveskite RSS kanalo URL</string>
<string name="blogs_rss_feeds_import_progress">Importuojamas RSS kanalas…</string>
<string name="blogs_rss_feeds_import_error">Atleiskite! Importuojant jūsų kanalą, įvyko klaida.</string> <string name="blogs_rss_feeds_import_error">Atleiskite! Importuojant jūsų kanalą, įvyko klaida.</string>
<string name="blogs_rss_feeds_import_title">Importuoti kanalą iš failo</string> <string name="blogs_rss_feeds_import_exists">Tas kanalas jau yra importuotas.</string>
<string name="blogs_rss_feeds">RSS kanalai</string> <string name="blogs_rss_feeds">RSS kanalai</string>
<string name="blogs_rss_feeds_manage_imported">Importuota:</string> <string name="blogs_rss_feeds_manage_imported">Importuota:</string>
<string name="blogs_rss_feeds_manage_author">Autorius:</string> <string name="blogs_rss_feeds_manage_author">Autorius:</string>
@@ -615,11 +604,8 @@
\nGalite įsidiegti Briar pašto dėžutę laisvame atsarginiame įrenginyje. Palikite įrenginį prijungtą prie maitinimo šaltinio ir belaidžio (Wi-Fi) ryšio, kad jis būtų pastoviai prijungtas prie interneto.</string> \nGalite įsidiegti Briar pašto dėžutę laisvame atsarginiame įrenginyje. Palikite įrenginį prijungtą prie maitinimo šaltinio ir belaidžio (Wi-Fi) ryšio, kad jis būtų pastoviai prijungtas prie interneto.</string>
<string name="mailbox_setup_download_link">Bendrinti atsisiuntimo nuorodą</string> <string name="mailbox_setup_download_link">Bendrinti atsisiuntimo nuorodą</string>
<string name="mailbox_setup_button_scan">Skenuoti pašto dėžutės QR kodą</string> <string name="mailbox_setup_button_scan">Skenuoti pašto dėžutės QR kodą</string>
<string name="mailbox_setup_connecting">Jungiamasi prie pašto dėžutės…</string>
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".--> <!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
<string name="mailbox_setup_connecting_info">Tai gali užtrukti iki %1s</string>
<string name="mailbox_setup_already_paired_title">Pašto dėžutė jau susieta</string> <string name="mailbox_setup_already_paired_title">Pašto dėžutė jau susieta</string>
<string name="mailbox_setup_already_paired_description">Atsiekite pašto dėžutę kitame įrenginyje ir bandykite dar kartą.</string>
<string name="mailbox_setup_io_error_title">Nepavyko prisijungti</string> <string name="mailbox_setup_io_error_title">Nepavyko prisijungti</string>
<string name="mailbox_setup_io_error_description">Įsitikinkite, kad abu įrenginiai yra prisijungę prie interneto ir bandykite dar kartą.</string> <string name="mailbox_setup_io_error_description">Įsitikinkite, kad abu įrenginiai yra prisijungę prie interneto ir bandykite dar kartą.</string>
<string name="mailbox_setup_assertion_error_title">Pašto dėžutės klaida</string> <string name="mailbox_setup_assertion_error_title">Pašto dėžutės klaida</string>
@@ -630,7 +616,6 @@
<string name="tor_offline_button_check">Tikrinti ryšio nustatymus</string> <string name="tor_offline_button_check">Tikrinti ryšio nustatymus</string>
<string name="mailbox_status_title">Pašto dėžutės būsena</string> <string name="mailbox_status_title">Pašto dėžutės būsena</string>
<string name="mailbox_status_connected_title">Pašto dėžutė veikia</string> <string name="mailbox_status_connected_title">Pašto dėžutė veikia</string>
<string name="mailbox_status_problem_title">Briar kyla nesklandumų jungiantis prie pašto dėžutės</string>
<string name="mailbox_status_failure_title">Pašto dėžutė yra neprieinama</string> <string name="mailbox_status_failure_title">Pašto dėžutė yra neprieinama</string>
<string name="mailbox_status_app_too_old_title">Briar yra per sena</string> <string name="mailbox_status_app_too_old_title">Briar yra per sena</string>
<string name="mailbox_status_app_too_old_message">Atnaujinkite Briar programėlę iki naujausios versijos ir bandykite dar kartą.</string> <string name="mailbox_status_app_too_old_message">Atnaujinkite Briar programėlę iki naujausios versijos ir bandykite dar kartą.</string>
@@ -645,10 +630,6 @@
<string name="mailbox_status_unlink_dialog_question">Ar tikrai norite atsieti pašto dėžutę?</string> <string name="mailbox_status_unlink_dialog_question">Ar tikrai norite atsieti pašto dėžutę?</string>
<string name="mailbox_status_unlink_no_wipe_title">Jūsų pašto dėžutė atsieta</string> <string name="mailbox_status_unlink_no_wipe_title">Jūsų pašto dėžutė atsieta</string>
<string name="mailbox_status_unlink_success">Jūsų pašto dėžutė atsieta</string> <string name="mailbox_status_unlink_success">Jūsų pašto dėžutė atsieta</string>
<string name="mailbox_error_notification_channel_title">Problemos su Briar pašto dėžute</string>
<string name="mailbox_error_notification_title">Briar pašto dėžutė yra neprieinama</string>
<string name="mailbox_error_notification_text">Bakstelėkite norėdami išspręsti problemą.</string>
<string name="mailbox_error_wizard_button">Išspręsti problemą</string>
<string name="mailbox_error_wizard_title">Pašto dėžutės nesklandumų šalinimo vediklis</string> <string name="mailbox_error_wizard_title">Pašto dėžutės nesklandumų šalinimo vediklis</string>
<!--About--> <!--About-->
<string name="about_title">Apie</string> <string name="about_title">Apie</string>
@@ -660,7 +641,6 @@
<string name="briar_changelog">\u2022 <a href="">Keitinių žurnalas</a></string> <string name="briar_changelog">\u2022 <a href="">Keitinių žurnalas</a></string>
<string name="briar_privacy_policy">\u2022 <a href="">Privatumo politika</a></string> <string name="briar_privacy_policy">\u2022 <a href="">Privatumo politika</a></string>
<!--Here translators can add their names or Transifex usernames(eg "Thanks to all the contributors at the Localization Lab, especially Tom, Matthew and Jerry")--> <!--Here translators can add their names or Transifex usernames(eg "Thanks to all the contributors at the Localization Lab, especially Tom, Matthew and Jerry")-->
<string name="translator_thanks">Dėkojame talkininkams iš Localization Lab, ypač Moo už vertimą į lietuvių kalbą</string>
<!--Conversation Settings--> <!--Conversation Settings-->
<string name="disappearing_messages_title">Išnykstančios žinutės</string> <string name="disappearing_messages_title">Išnykstančios žinutės</string>
<string name="disappearing_messages_explanation_long">Įjungus šį nustatymą, naujos žinutės <string name="disappearing_messages_explanation_long">Įjungus šį nustatymą, naujos žinutės

View File

@@ -460,6 +460,7 @@
<string name="blogs_rss_feeds_import_button">တင်သွင်းမည်</string> <string name="blogs_rss_feeds_import_button">တင်သွင်းမည်</string>
<string name="blogs_rss_feeds_import_hint">RSS သတင်းပို့စ်အလွှာ၏ URL ရိုက်ထည့်ပေးပါ</string> <string name="blogs_rss_feeds_import_hint">RSS သတင်းပို့စ်အလွှာ၏ URL ရိုက်ထည့်ပေးပါ</string>
<string name="blogs_rss_feeds_import_error">ဝမ်းနည်းပါသည်! သင့် သတင်းပို့စ်အလွှာအား တင်သွင်းရာတွင် ပျက်ကွက်မှု ဖြစ်ခဲ့ပါသည်။</string> <string name="blogs_rss_feeds_import_error">ဝမ်းနည်းပါသည်! သင့် သတင်းပို့စ်အလွှာအား တင်သွင်းရာတွင် ပျက်ကွက်မှု ဖြစ်ခဲ့ပါသည်။</string>
<string name="blogs_rss_feeds_import_exists">Feed ကို တင်ပို့ပြီး ဖြစ်သည်။</string>
<string name="blogs_rss_feeds">RSS သတင်းလွှာများ</string> <string name="blogs_rss_feeds">RSS သတင်းလွှာများ</string>
<string name="blogs_rss_feeds_manage_imported">တင်သွင်းထားသော</string> <string name="blogs_rss_feeds_manage_imported">တင်သွင်းထားသော</string>
<string name="blogs_rss_feeds_manage_author">စာရေးဆရာ -</string> <string name="blogs_rss_feeds_manage_author">စာရေးဆရာ -</string>

View File

@@ -477,6 +477,7 @@
<string name="blogs_rss_feeds_import_button">Importer</string> <string name="blogs_rss_feeds_import_button">Importer</string>
<string name="blogs_rss_feeds_import_hint">Skriv inn nettadresse for RSS-strøm</string> <string name="blogs_rss_feeds_import_hint">Skriv inn nettadresse for RSS-strøm</string>
<string name="blogs_rss_feeds_import_error">Vi beklager! Feil under importering av strøm.</string> <string name="blogs_rss_feeds_import_error">Vi beklager! Feil under importering av strøm.</string>
<string name="blogs_rss_feeds_import_exists">Den feed\'en er importert allerede</string>
<string name="blogs_rss_feeds">RSS-feed\'er</string> <string name="blogs_rss_feeds">RSS-feed\'er</string>
<string name="blogs_rss_feeds_manage_imported">Importert:</string> <string name="blogs_rss_feeds_manage_imported">Importert:</string>
<string name="blogs_rss_feeds_manage_author">Forfatter:</string> <string name="blogs_rss_feeds_manage_author">Forfatter:</string>

View File

@@ -244,7 +244,6 @@
<string name="menu_contact">Kontakt</string> <string name="menu_contact">Kontakt</string>
<!--Adding Contacts--> <!--Adding Contacts-->
<string name="add_contact_title">Dodaj kontakt w pobliżu</string> <string name="add_contact_title">Dodaj kontakt w pobliżu</string>
<string name="add_contact_error_two_way">Czy oboje skanowaliście nawzajem swoje kody QR?</string>
<string name="face_to_face">Musisz spotkać się z osobą którą chcesz dodać jako kontakt.\n\nTo uniemożliwi komukolwiek udawanie Ciebie lub czytanie Twoich wiadomości w przyszłości.</string> <string name="face_to_face">Musisz spotkać się z osobą którą chcesz dodać jako kontakt.\n\nTo uniemożliwi komukolwiek udawanie Ciebie lub czytanie Twoich wiadomości w przyszłości.</string>
<string name="continue_button">Kontynuuj</string> <string name="continue_button">Kontynuuj</string>
<string name="try_again_button">Spróbuj ponownie</string> <string name="try_again_button">Spróbuj ponownie</string>
@@ -252,7 +251,6 @@
<string name="exchanging_contact_details">Wymienianie szczegółów dotyczących kontatku\u2026</string> <string name="exchanging_contact_details">Wymienianie szczegółów dotyczących kontatku\u2026</string>
<string name="contact_added_toast">Kontakt dodany: %s</string> <string name="contact_added_toast">Kontakt dodany: %s</string>
<string name="contact_already_exists">Kontakt %s już istnieje</string> <string name="contact_already_exists">Kontakt %s już istnieje</string>
<string name="contact_already_exists_general">Kontakt już istnieje</string>
<string name="qr_code_invalid">Kod QR jest nieprawidłowy</string> <string name="qr_code_invalid">Kod QR jest nieprawidłowy</string>
<string name="qr_code_too_old_1">Zeskanowany kod QR pochodzi ze starszej wersji Briar.\n\nProszę poprosić Twój kontakt o aktualizację do najnowszej wersji, a następnie spróbować ponownie.</string> <string name="qr_code_too_old_1">Zeskanowany kod QR pochodzi ze starszej wersji Briar.\n\nProszę poprosić Twój kontakt o aktualizację do najnowszej wersji, a następnie spróbować ponownie.</string>
<string name="qr_code_too_new_1">Zeskanowany kod QR pochodzi z nowszej wersji programu Briar.\n\nProszę zaktualizować go do najnowszej wersji, a następnie spróbować ponownie.</string> <string name="qr_code_too_new_1">Zeskanowany kod QR pochodzi z nowszej wersji programu Briar.\n\nProszę zaktualizować go do najnowszej wersji, a następnie spróbować ponownie.</string>
@@ -261,7 +259,6 @@
<string name="authenticating_with_device">Autoryzowanie z urządzeniem\u2026</string> <string name="authenticating_with_device">Autoryzowanie z urządzeniem\u2026</string>
<string name="connection_error_title">Nie udało się połączyć z kontaktem</string> <string name="connection_error_title">Nie udało się połączyć z kontaktem</string>
<string name="connection_error_feedback">Jeśli problem będzie występować dalej, proszę <a href="feedback">wysłać opinię</a> aby pomóc nam ulepszyć aplikację.</string> <string name="connection_error_feedback">Jeśli problem będzie występować dalej, proszę <a href="feedback">wysłać opinię</a> aby pomóc nam ulepszyć aplikację.</string>
<string name="info_both_must_scan">Oboje musicie skanować nawzajem swoje kody QR</string>
<!--Adding Contacts Remotely--> <!--Adding Contacts Remotely-->
<string name="add_contact_remotely_title_case">Dodaj Kontakt na odległość</string> <string name="add_contact_remotely_title_case">Dodaj Kontakt na odległość</string>
<string name="add_contact_nearby_title">Dodaj kontakt w pobliżu</string> <string name="add_contact_nearby_title">Dodaj kontakt w pobliżu</string>
@@ -321,7 +318,6 @@
<string name="different_person_button">Inna osoba</string> <string name="different_person_button">Inna osoba</string>
<string name="duplicate_link_dialog_text_3">%1$si %2$s wysłał ci ten sam link.\n\nJeden z nich może próbować odkryć, kim są twoje kontakty.\n\nNie mów im, że otrzymałeś ten sam link od kogoś innego.</string> <string name="duplicate_link_dialog_text_3">%1$si %2$s wysłał ci ten sam link.\n\nJeden z nich może próbować odkryć, kim są twoje kontakty.\n\nNie mów im, że otrzymałeś ten sam link od kogoś innego.</string>
<string name="pending_contact_updated_toast">Oczekujący kontakt zaktualizowany</string> <string name="pending_contact_updated_toast">Oczekujący kontakt zaktualizowany</string>
<string name="info_both_must_enter_links">Oboje musicie dodać swoje linki</string>
<!--Peer trust levels--> <!--Peer trust levels-->
<string name="peer_trust_level_unverified">Niezweryfikowane kontakty</string> <string name="peer_trust_level_unverified">Niezweryfikowane kontakty</string>
<string name="peer_trust_level_verified">Zweryfikowane kontakty</string> <string name="peer_trust_level_verified">Zweryfikowane kontakty</string>
@@ -355,7 +351,6 @@
<string name="connect_via_bluetooth_intro">W przypadku gdy połączenia przez Bluetooth nie działają automatycznie, możesz użyć tego ekranu do połączenia ręcznego.\n\nTwój kontakt musi znajdować się w pobliżu, żeby to zadziałało.\n\nTy i Twój kontakt powinniście jednocześnie wcisnąć \"Start\".</string> <string name="connect_via_bluetooth_intro">W przypadku gdy połączenia przez Bluetooth nie działają automatycznie, możesz użyć tego ekranu do połączenia ręcznego.\n\nTwój kontakt musi znajdować się w pobliżu, żeby to zadziałało.\n\nTy i Twój kontakt powinniście jednocześnie wcisnąć \"Start\".</string>
<string name="connect_via_bluetooth_already_discovering">Próba połączenia przez Bluetooth jest już w trakcie. Spróbuj ponownie za chwilę.</string> <string name="connect_via_bluetooth_already_discovering">Próba połączenia przez Bluetooth jest już w trakcie. Spróbuj ponownie za chwilę.</string>
<string name="connect_via_bluetooth_no_location_permission">Nie można kontynuować bez dostępu do lokalizacji</string> <string name="connect_via_bluetooth_no_location_permission">Nie można kontynuować bez dostępu do lokalizacji</string>
<string name="connect_via_bluetooth_no_bluetooth_permission">Nie można kontynuować bez pozwolenia na urządzenia w pobliżu</string>
<string name="connect_via_bluetooth_start">Łączenie przez Bluetooth...</string> <string name="connect_via_bluetooth_start">Łączenie przez Bluetooth...</string>
<string name="connect_via_bluetooth_success">Udało się połączyć przez Bluetooth.</string> <string name="connect_via_bluetooth_success">Udało się połączyć przez Bluetooth.</string>
<string name="connect_via_bluetooth_error">Nie można się połączyć przez Bluetooth.</string> <string name="connect_via_bluetooth_error">Nie można się połączyć przez Bluetooth.</string>
@@ -458,10 +453,6 @@
<string name="forum_declined_toast">Zaproszenie odrzucone</string> <string name="forum_declined_toast">Zaproszenie odrzucone</string>
<string name="shared_by_format">Udostępnione przez %s</string> <string name="shared_by_format">Udostępnione przez %s</string>
<string name="forum_invitation_already_sharing">Już udostępnione</string> <string name="forum_invitation_already_sharing">Już udostępnione</string>
<string name="forum_invitation_already_invited">Wysłano już zaproszenie</string>
<string name="forum_invitation_invite_received">Odebrano już zaproszenie</string>
<string name="forum_invitation_not_supported">Nie obsługiwane przez ten kontakt</string>
<string name="forum_invitation_error">Błąd. Jest to błąd w naszej aplikacji, to nie twoja wina</string>
<string name="forum_invitation_response_accepted_sent">Przyjąłeś zaproszenie do forum od %s</string> <string name="forum_invitation_response_accepted_sent">Przyjąłeś zaproszenie do forum od %s</string>
<string name="forum_invitation_response_declined_sent">Odrzuciłeś zaproszenie do forum od %s</string> <string name="forum_invitation_response_declined_sent">Odrzuciłeś zaproszenie do forum od %s</string>
<string name="forum_invitation_response_declined_auto">Zaproszenie do forum od %s zostało automatycznie odrzucone.</string> <string name="forum_invitation_response_declined_auto">Zaproszenie do forum od %s zostało automatycznie odrzucone.</string>
@@ -514,9 +505,8 @@
<string name="blogs_rss_feeds_import">Zaimportuj kanał RSS</string> <string name="blogs_rss_feeds_import">Zaimportuj kanał RSS</string>
<string name="blogs_rss_feeds_import_button">Zaimportuj</string> <string name="blogs_rss_feeds_import_button">Zaimportuj</string>
<string name="blogs_rss_feeds_import_hint">Wprowadź adres URL do kanału RSS</string> <string name="blogs_rss_feeds_import_hint">Wprowadź adres URL do kanału RSS</string>
<string name="blogs_rss_feeds_import_progress">Importowanie kanału RSS…</string>
<string name="blogs_rss_feeds_import_error">Przepraszamy! Wystąpił błąd podczas importowania twojego kanału RSS</string> <string name="blogs_rss_feeds_import_error">Przepraszamy! Wystąpił błąd podczas importowania twojego kanału RSS</string>
<string name="blogs_rss_feeds_import_title">Importuj kanał z pliku</string> <string name="blogs_rss_feeds_import_exists">Ten feed został już zaimportowany.</string>
<string name="blogs_rss_feeds">Feedy RSS</string> <string name="blogs_rss_feeds">Feedy RSS</string>
<string name="blogs_rss_feeds_manage_imported">Zaimportowane:</string> <string name="blogs_rss_feeds_manage_imported">Zaimportowane:</string>
<string name="blogs_rss_feeds_manage_author">Autor:</string> <string name="blogs_rss_feeds_manage_author">Autor:</string>
@@ -628,12 +618,7 @@
<string name="mailbox_setup_download_link">Udostępnij łącze pobierania</string> <string name="mailbox_setup_download_link">Udostępnij łącze pobierania</string>
<string name="mailbox_setup_button_scan">Zeskanuj kod QR aplikacji Mailbox</string> <string name="mailbox_setup_button_scan">Zeskanuj kod QR aplikacji Mailbox</string>
<string name="permission_camera_qr_denied_body">Odmówiłeś dostępu do aparatu, ale zeskanowanie kodu QR wymaga użycia aparatu.\n\nRozważ przyznanie dostępu.</string> <string name="permission_camera_qr_denied_body">Odmówiłeś dostępu do aparatu, ale zeskanowanie kodu QR wymaga użycia aparatu.\n\nRozważ przyznanie dostępu.</string>
<string name="mailbox_setup_connecting">Łączenie się ze Skrzynką odbiorczą…</string>
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".--> <!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
<string name="mailbox_setup_connecting_info">Może to potrwać do %1s</string>
<string name="mailbox_qr_code_too_old">Zeskanowany kod QR pochodzi ze starszej wersji skrzynki odbiorczej Briar.\n\nProszę zaktualizować ją do najnowszej wersji, a następnie spróbować ponownie.</string>
<string name="mailbox_qr_code_too_new">Zeskanowany kod QR pochodzi z nowszej wersji skrzynki odbiorczej Briar.\n\nProszę zaktualizować ją do najnowszej wersji, a następnie spróbować ponownie.</string>
<string name="mailbox_setup_qr_code_wrong_description">Zeskanowany kod QR nie pochodzi ze skrzynki odbiorczej Briar. Otwórz skrzynkę odbiorczą Briar na urządzeniu z Twoją skrzynką i zeskanuj wyświetlany kod QR. </string>
<string name="mailbox_setup_already_paired_title">Mailbox już podłączony</string> <string name="mailbox_setup_already_paired_title">Mailbox już podłączony</string>
<string name="mailbox_setup_already_paired_description">Odłącz Mailbox na drugim urządzeniu i spróbuj ponownie.</string> <string name="mailbox_setup_already_paired_description">Odłącz Mailbox na drugim urządzeniu i spróbuj ponownie.</string>
<string name="mailbox_setup_io_error_title">Nie udało się połączyć</string> <string name="mailbox_setup_io_error_title">Nie udało się połączyć</string>
@@ -771,15 +756,11 @@ Brak dostępu do aparatu. Spróbuj ponownie, może po ponownym uruchomieniu urz
<string name="permission_location_request_body">Aby odkryć urządzenia Bluetooth, Briar potrzebuje zezwolenia na dostęp do twojej lokalizacji.\n\nBriar nie przechowuje twojej lokalizacji ani nie udostępnia jej nikomu.</string> <string name="permission_location_request_body">Aby odkryć urządzenia Bluetooth, Briar potrzebuje zezwolenia na dostęp do twojej lokalizacji.\n\nBriar nie przechowuje twojej lokalizacji ani nie udostępnia jej nikomu.</string>
<string name="permission_camera_location_title">Kamera i lokalizacja</string> <string name="permission_camera_location_title">Kamera i lokalizacja</string>
<string name="permission_camera_location_request_body">Aby zeskanować kod QR, Briar potrzebuje dostępu do kamery.\n\nAby odkryć urządzenia Bluetooth, Briar potrzebuje zezwolenia na dostęp do Twojej lokalizacji.\n\nBriar nie przechowuje Twojej lokalizacji ani nie udostępnia jej nikomu.</string> <string name="permission_camera_location_request_body">Aby zeskanować kod QR, Briar potrzebuje dostępu do kamery.\n\nAby odkryć urządzenia Bluetooth, Briar potrzebuje zezwolenia na dostęp do Twojej lokalizacji.\n\nBriar nie przechowuje Twojej lokalizacji ani nie udostępnia jej nikomu.</string>
<string name="permission_camera_bluetooth_title">Aparat i urządzenia w pobliżu</string>
<string name="permission_camera_denied_body">Odmówiłeś dostępu do aparatu, lecz dodawanie kontaktów wymaga jego użycia.\n\nProszę rozważyć udzielenie dostępu do aparatu</string> <string name="permission_camera_denied_body">Odmówiłeś dostępu do aparatu, lecz dodawanie kontaktów wymaga jego użycia.\n\nProszę rozważyć udzielenie dostępu do aparatu</string>
<string name="permission_location_denied_body">Zabroniłeś dostępu do Twojej lokalizacji, ale Briar potrzebuje tego uprawnienia do wykrywania urządzeń Bluetooth.\n\nRozważ przyznanie tego dostępu.</string> <string name="permission_location_denied_body">Zabroniłeś dostępu do Twojej lokalizacji, ale Briar potrzebuje tego uprawnienia do wykrywania urządzeń Bluetooth.\n\nRozważ przyznanie tego dostępu.</string>
<string name="permission_location_setting_title">Ustawienia lokalizacji</string> <string name="permission_location_setting_title">Ustawienia lokalizacji</string>
<string name="permission_location_setting_body">Ustawienie lokalizacji urządzenia musi być włączone, aby można było znaleźć inne urządzenia przez Bluetooth. Włącz lokalizację, aby kontynuować. Później możesz ją ponownie wyłączyć.</string> <string name="permission_location_setting_body">Ustawienie lokalizacji urządzenia musi być włączone, aby można było znaleźć inne urządzenia przez Bluetooth. Włącz lokalizację, aby kontynuować. Później możesz ją ponownie wyłączyć.</string>
<string name="permission_location_setting_button">Włącz lokalizację</string> <string name="permission_location_setting_button">Włącz lokalizację</string>
<string name="permission_bluetooth_title">Pozwolenie do urządzeń w pobliżu</string>
<string name="permission_bluetooth_body">Aby korzystać z komunikacji Bluetooth, Briar potrzebuje uprawnień do znajdowania i łączenia się z pobliskimi urządzeniami.</string>
<string name="permission_bluetooth_denied_body">Odmówiono dostępu do pobliskich urządzeń, ale Briar potrzebuje tego uprawnienia, aby korzystać z Bluetooth.\n\nRozważ udzielenie dostępu.</string>
<string name="qr_code">Kod QR</string> <string name="qr_code">Kod QR</string>
<string name="show_qr_code_fullscreen">Pokaż QR na pełnym ekranie</string> <string name="show_qr_code_fullscreen">Pokaż QR na pełnym ekranie</string>
<!--App Locking--> <!--App Locking-->
@@ -802,9 +783,7 @@ Brak dostępu do aparatu. Spróbuj ponownie, może po ponownym uruchomieniu urz
<string name="hotspot_notification_title">Udostępnianie Briar offline</string> <string name="hotspot_notification_title">Udostępnianie Briar offline</string>
<string name="hotspot_button_connected">Następny</string> <string name="hotspot_button_connected">Następny</string>
<string name="permission_hotspot_location_request_body">Aby utworzyć hotspot Wi-Fi, Briar potrzebuje uprawnienia do dostępu do Twojej lokalizacji.\n\nBriar nie przechowuje Twojej lokalizacji ani nie udostępnia jej nikomu.</string> <string name="permission_hotspot_location_request_body">Aby utworzyć hotspot Wi-Fi, Briar potrzebuje uprawnienia do dostępu do Twojej lokalizacji.\n\nBriar nie przechowuje Twojej lokalizacji ani nie udostępnia jej nikomu.</string>
<string name="permission_hotspot_location_request_precise_body">Aby utworzyć hotspot Wi-Fi, Briar potrzebuje uprawnienia do dostępu do Twojej dokładnej lokalizacji.\n\nBriar nie przechowuje Twojej lokalizacji ani nie udostępnia jej nikomu.</string>
<string name="permission_hotspot_location_denied_body">Zabroniłeś dostępu do Twojej lokalizacji, ale Briar potrzebuje tego uprawnienia do tworzenia hotspotu Wi-Fi.\n\nRozważ przyznanie tego dostępu.</string> <string name="permission_hotspot_location_denied_body">Zabroniłeś dostępu do Twojej lokalizacji, ale Briar potrzebuje tego uprawnienia do tworzenia hotspotu Wi-Fi.\n\nRozważ przyznanie tego dostępu.</string>
<string name="permission_hotspot_location_denied_precise_body">Zabroniono dostępu do dokładnej lokalizacji. Briar potrzebuje tego uprawnienia do tworzenia hotspotu Wi-Fi.\n\nRozważ przyznanie tego dostępu.</string>
<string name="wifi_settings_title">Ustawienia Wi-Fi</string> <string name="wifi_settings_title">Ustawienia Wi-Fi</string>
<string name="wifi_settings_request_enable_body">Aby utworzyć hotspot Wi-Fi, Briar potrzebuje użyć Wi-Fi. Włącz Wi-Fi.</string> <string name="wifi_settings_request_enable_body">Aby utworzyć hotspot Wi-Fi, Briar potrzebuje użyć Wi-Fi. Włącz Wi-Fi.</string>
<string name="hotspot_tab_manual">Manualne</string> <string name="hotspot_tab_manual">Manualne</string>

View File

@@ -488,6 +488,7 @@
<string name="blogs_rss_feeds_import_button">Importar</string> <string name="blogs_rss_feeds_import_button">Importar</string>
<string name="blogs_rss_feeds_import_hint">Entre a URL do feed RSS</string> <string name="blogs_rss_feeds_import_hint">Entre a URL do feed RSS</string>
<string name="blogs_rss_feeds_import_error">Nós lamentamos! Houve um erro ao importar seu Feed.</string> <string name="blogs_rss_feeds_import_error">Nós lamentamos! Houve um erro ao importar seu Feed.</string>
<string name="blogs_rss_feeds_import_exists">Esse feed já foi importado.</string>
<string name="blogs_rss_feeds">Feeds RSS</string> <string name="blogs_rss_feeds">Feeds RSS</string>
<string name="blogs_rss_feeds_manage_imported">Importado:</string> <string name="blogs_rss_feeds_manage_imported">Importado:</string>
<string name="blogs_rss_feeds_manage_author">Autor:</string> <string name="blogs_rss_feeds_manage_author">Autor:</string>

View File

@@ -243,7 +243,6 @@
<string name="exchanging_contact_details">Se face schimbul de date de contact\u2026</string> <string name="exchanging_contact_details">Se face schimbul de date de contact\u2026</string>
<string name="contact_added_toast">Contact adăugat: %s</string> <string name="contact_added_toast">Contact adăugat: %s</string>
<string name="contact_already_exists">Contactul %s există deja</string> <string name="contact_already_exists">Contactul %s există deja</string>
<string name="contact_already_exists_general">Contactul există deja</string>
<string name="qr_code_invalid">Codul QR este nevalid!</string> <string name="qr_code_invalid">Codul QR este nevalid!</string>
<string name="qr_code_too_old_1">Codul QR pe care l-ați scanat provine de la o versiune Briar mai veche.\n\nSolicitați contactului să actualizeze aplicația la cea mai recentă versiune, după care încercați din nou.</string> <string name="qr_code_too_old_1">Codul QR pe care l-ați scanat provine de la o versiune Briar mai veche.\n\nSolicitați contactului să actualizeze aplicația la cea mai recentă versiune, după care încercați din nou.</string>
<string name="qr_code_too_new_1">Codul QR pe care l-ați scanat provine de la o versiune Briar mai nouă.\n\nActualizați aplicația la cea mai recentă versiune, după care încercați din nou.</string> <string name="qr_code_too_new_1">Codul QR pe care l-ați scanat provine de la o versiune Briar mai nouă.\n\nActualizați aplicația la cea mai recentă versiune, după care încercați din nou.</string>
@@ -447,10 +446,6 @@
<string name="forum_declined_toast">Invitația a fost refuzată</string> <string name="forum_declined_toast">Invitația a fost refuzată</string>
<string name="shared_by_format">Partajat de %s</string> <string name="shared_by_format">Partajat de %s</string>
<string name="forum_invitation_already_sharing">Deja partajat</string> <string name="forum_invitation_already_sharing">Deja partajat</string>
<string name="forum_invitation_already_invited">Invitație deja trimisă</string>
<string name="forum_invitation_invite_received">Invitație deja primită</string>
<string name="forum_invitation_not_supported">Nu este susținut de acest contact</string>
<string name="forum_invitation_error">Eroare. Aceasta este o eroare și nu este vina dumneavoastră</string>
<string name="forum_invitation_response_accepted_sent">Ați acceptat invitația la forum de la %s.</string> <string name="forum_invitation_response_accepted_sent">Ați acceptat invitația la forum de la %s.</string>
<string name="forum_invitation_response_declined_sent">Ați refuzat invitația la forum de la %s.</string> <string name="forum_invitation_response_declined_sent">Ați refuzat invitația la forum de la %s.</string>
<string name="forum_invitation_response_declined_auto">Invitația la forumu de la %s a fost refuzată automat.</string> <string name="forum_invitation_response_declined_auto">Invitația la forumu de la %s a fost refuzată automat.</string>
@@ -502,9 +497,8 @@
<string name="blogs_rss_feeds_import">Importați flux RSS</string> <string name="blogs_rss_feeds_import">Importați flux RSS</string>
<string name="blogs_rss_feeds_import_button">Importați</string> <string name="blogs_rss_feeds_import_button">Importați</string>
<string name="blogs_rss_feeds_import_hint">Introduceți adresa URL a fluxului RSS</string> <string name="blogs_rss_feeds_import_hint">Introduceți adresa URL a fluxului RSS</string>
<string name="blogs_rss_feeds_import_progress">Importarea RSS Feed…</string>
<string name="blogs_rss_feeds_import_error">Ne pare rău, dar a apărut o eroare la importarea fluxului dvs.</string> <string name="blogs_rss_feeds_import_error">Ne pare rău, dar a apărut o eroare la importarea fluxului dvs.</string>
<string name="blogs_rss_feeds_import_title">Importați feed din fișier</string> <string name="blogs_rss_feeds_import_exists">Fluxul respectiv este deja importat.</string>
<string name="blogs_rss_feeds">Fluxuri RSS</string> <string name="blogs_rss_feeds">Fluxuri RSS</string>
<string name="blogs_rss_feeds_manage_imported">Importat:</string> <string name="blogs_rss_feeds_manage_imported">Importat:</string>
<string name="blogs_rss_feeds_manage_author">Autor:</string> <string name="blogs_rss_feeds_manage_author">Autor:</string>

View File

@@ -252,7 +252,6 @@
<string name="exchanging_contact_details">Обмен контактными данными\u2026</string> <string name="exchanging_contact_details">Обмен контактными данными\u2026</string>
<string name="contact_added_toast">Контакт добавлен: %s</string> <string name="contact_added_toast">Контакт добавлен: %s</string>
<string name="contact_already_exists">Контакт %s уже существует</string> <string name="contact_already_exists">Контакт %s уже существует</string>
<string name="contact_already_exists_general">Контакт уже существует</string>
<string name="qr_code_invalid">Неверный QR-код</string> <string name="qr_code_invalid">Неверный QR-код</string>
<string name="qr_code_too_old_1">QR-код, который вы сосканировали, сгенерирован в старой версии Briar.\n\nПопросите вашего собеседника обновиться до последней версии и повторите попытку.</string> <string name="qr_code_too_old_1">QR-код, который вы сосканировали, сгенерирован в старой версии Briar.\n\nПопросите вашего собеседника обновиться до последней версии и повторите попытку.</string>
<string name="qr_code_too_new_1">QR-код, который вы сосканировали, сгенерирован в новой версии Briar.\n\nОбновите приложение до последней версии и повторите попытку.</string> <string name="qr_code_too_new_1">QR-код, который вы сосканировали, сгенерирован в новой версии Briar.\n\nОбновите приложение до последней версии и повторите попытку.</string>
@@ -463,7 +462,7 @@
<string name="forum_invitation_already_invited">Приглашение уже отправлено</string> <string name="forum_invitation_already_invited">Приглашение уже отправлено</string>
<string name="forum_invitation_invite_received">Приглашение уже получено</string> <string name="forum_invitation_invite_received">Приглашение уже получено</string>
<string name="forum_invitation_not_supported">Не поддерживается этим контактом</string> <string name="forum_invitation_not_supported">Не поддерживается этим контактом</string>
<string name="forum_invitation_error">Это ошибка программы. Вы тут ни причем.</string> <string name="forum_invitation_error">Ошибка. Это программная ошибка, а не ваша вина</string>
<string name="forum_invitation_response_accepted_sent">Вы приняли приглашение на форум от %s.</string> <string name="forum_invitation_response_accepted_sent">Вы приняли приглашение на форум от %s.</string>
<string name="forum_invitation_response_declined_sent">Вы отклонили приглашение на форум от %s.</string> <string name="forum_invitation_response_declined_sent">Вы отклонили приглашение на форум от %s.</string>
<string name="forum_invitation_response_declined_auto">Приглашение на форум от %s было отклонено автоматически.</string> <string name="forum_invitation_response_declined_auto">Приглашение на форум от %s было отклонено автоматически.</string>
@@ -516,9 +515,8 @@
<string name="blogs_rss_feeds_import">Импорт RSS-ленты</string> <string name="blogs_rss_feeds_import">Импорт RSS-ленты</string>
<string name="blogs_rss_feeds_import_button">Импорт</string> <string name="blogs_rss_feeds_import_button">Импорт</string>
<string name="blogs_rss_feeds_import_hint">Введите URL-адрес RSS-ленты</string> <string name="blogs_rss_feeds_import_hint">Введите URL-адрес RSS-ленты</string>
<string name="blogs_rss_feeds_import_progress">Импорт RSS-лент...</string>
<string name="blogs_rss_feeds_import_error">Мы сожалеем! Произошла ошибка при импорте ленты.</string> <string name="blogs_rss_feeds_import_error">Мы сожалеем! Произошла ошибка при импорте ленты.</string>
<string name="blogs_rss_feeds_import_title">Импорт ленты из файла</string> <string name="blogs_rss_feeds_import_exists">Эта лента уже импортирована.</string>
<string name="blogs_rss_feeds">RSS-ленты</string> <string name="blogs_rss_feeds">RSS-ленты</string>
<string name="blogs_rss_feeds_manage_imported">Импортирован:</string> <string name="blogs_rss_feeds_manage_imported">Импортирован:</string>
<string name="blogs_rss_feeds_manage_author">Автор:</string> <string name="blogs_rss_feeds_manage_author">Автор:</string>

View File

@@ -1,901 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources xmlns:tools="http://schemas.android.com/tools">
<!--Setup-->
<string name="setup_title">Vitajte v Briar</string>
<string name="setup_name_explanation">Vaša prezývka sa bude zobrazovať pri každom obsahu, ktorý zverejníte. Po vytvorení účtu ju už nemôžete zmeniť.</string>
<string name="setup_next">Ďalej</string>
<string name="setup_password_intro">Zvoľte si heslo</string>
<string name="setup_password_explanation">Vaše konto Briar je uložené šifrovane vo vašom zariadení, nie v cloude. Ak zabudnete heslo alebo odinštalujete aplikáciu Briar, konto sa nedá obnoviť.\n\nVyberte si dlhé heslo, ktoré je ťažké uhádnuť, napríklad štyri náhodné slová alebo desať náhodných písmen, číslic a symbolov.</string>
<string name="dnkm_doze_intro">Aby ste mohli prijímať správy, musí byť Briar pripojený na pozadí.</string>
<string name="dnkm_doze_explanation">Aby ste mohli prijímať správy, musí byť Briar pripojený na pozadí. Vypnite optimalizáciu batérie, aby Briar mohol zostať pripojený.</string>
<string name="choose_nickname">Vyberte si svoju prezývku</string>
<string name="choose_password">Zvoľte si heslo</string>
<string name="confirm_password">Potvrďte svoje heslo</string>
<string name="name_too_long">Meno je príliš dlhé</string>
<string name="password_too_weak">Heslo je príliš slabé</string>
<string name="passwords_do_not_match">Hesla sa nezhodujú</string>
<string name="create_account_button">Vytvoriť účet</string>
<string name="more_info">Viac informácií</string>
<string name="don_t_ask_again">Nepýtať sa znova</string>
<string name="dnkm_huawei_protected_text">Ťuknite na tlačidlo nižšie a na obrazovke \"Chránené aplikácie\" skontrolujte, či je aplikácia Briar chránená.</string>
<string name="dnkm_huawei_protected_button">Ochrániť Briar</string>
<string name="dnkm_huawei_protected_help">Ak Briar nie je pridaný do zoznamu chránených aplikácií, nebude môcť byť spustený na pozadí.</string>
<string name="dnkm_huawei_app_launch_text">Ťuknite na tlačidlo nižšie, otvorte obrazovku \"Spustenie aplikácie\" a uistite sa, že je Briar nastavený na \"Spravovať ručne\".</string>
<string name="dnkm_huawei_app_launch_help">Ak Briar nie je na obrazovke \"Spustenie aplikácie\" nastavený na možnosť \"Spravovať ručne\", nebude môcť byť spustený na pozadí.</string>
<string name="dnkm_xiaomi_text">Ak má byť aplikácia Briar spustená na pozadí, musí byť uzamknutá v zozname posledných aplikácií.</string>
<string name="dnkm_xiaomi_button">Ochrániť Briar</string>
<string name="dnkm_xiaomi_help">Ak Briar nie je uzamknutý v zozname posledných aplikácií, nebude môcť byť spustený na pozadí.</string>
<string name="dnkm_xiaomi_dialog_body_old">1. Otvorte zoznam posledných aplikácií (nazývaný aj prepínač aplikácií)\n\n2. Potiahnite prstom nadol na obrázok Briar, aby sa zobrazila ikona visiaceho zámku\n\n3. Ak visiaci zámok nie je zamknutý, ťuknutím naň ho zamknite</string>
<string name="dnkm_xiaomi_dialog_body_new">1. Otvorte zoznam posledných aplikácií (nazývaný aj prepínač aplikácií)\n\n2. Ak má Briar vedľa svojho názvu malý obrázok visiaceho zámku, nemusíte robiť nič\n\n3. Ak tam visiaci zámok nie je, stlačte a podržte obrázok Briar, kým sa nezobrazí tlačidlo visiaceho zámku, a potom naň ťuknite</string>
<string name="dnkm_xiaomi_lock_apps_text">Ťuknutím na tlačidlo nižšie otvorte nastavenia zabezpečenia. Klepnite na položku \"Zvýšenie rýchlosti\", potom klepnite na položku \"Uzamknúť aplikácie\" a uistite sa, že je Briar nastavený na možnosť \"Uzamknuté\".</string>
<string name="dnkm_xiaomi_lock_apps_help">Ak Briar nie je na obrazovke \"Uzamknuté aplikácie\" nastavený na možnosť \"Uzamknuté\", nebude môcť byť spustený na pozadí.</string>
<string name="dnkm_warning_dozed_1">Aplikáciu Briar sa nepodarilo spustiť na pozadí</string>
<!--Login-->
<string name="enter_password">Heslo</string>
<string name="try_again">Nesprávne heslo, skúste to znova</string>
<string name="dialog_title_cannot_check_password">Nie je možné skontrolovať heslo</string>
<string name="dialog_message_cannot_check_password">Briar nemôže skontrolovať vaše heslo. Skúste tento problém vyriešiť reštartovaním zariadenia.</string>
<string name="sign_in_button">Prihlásiť sa</string>
<string name="forgotten_password">Zabudol som svoje heslo</string>
<string name="dialog_title_lost_password">Zabudnuté heslo</string>
<string name="dialog_message_lost_password">Vaše konto Briar je uložené šifrovane vo vašom zariadení, nie v cloude, takže vaše heslo nemôžeme resetovať. Chcete odstrániť svoj účet a začať znova?\n\nPozor: Vaše identity, kontakty a správy budú natrvalo stratené.</string>
<string name="startup_failed_activity_title">Zlyhanie spustenia aplikácie Briar</string>
<string name="startup_failed_clock_error">Briar sa nepodarilo spustiť, pretože hodiny vášho zariadenia sú nesprávne.\n\nProsím, nastavte hodiny vášho zariadenia na správny čas a skúste to znova.</string>
<string name="startup_failed_db_error">Aplikácii Briar sa nepodarilo otvoriť databázu, ktorá obsahuje vaše konto, kontakty a správy.\n\nProsím, aktualizujte na najnovšiu verziu aplikácie a skúste to znova, alebo si nastavte nové konto výberom možnosti \"Zabudol som heslo\" vo výzve na zadanie hesla.</string>
<string name="startup_failed_data_too_old_error">Vaše konto bolo vytvorené v starej verzii tejto aplikácie a v tejto verzii sa nedá otvoriť.\n\nMusíte buď nainštalovať starú verziu, alebo nastaviť nové konto výberom možnosti \"Zabudol som heslo\" vo výzve na zadanie hesla.</string>
<string name="startup_failed_data_too_new_error">Vaše konto bolo vytvorené s novšou verziou tejto aplikácie a s touto verziou ho nemožno otvoriť.\n\nProsím, aktualizujte na najnovšiu verziu a skúste to znova.</string>
<string name="startup_failed_service_error">Briar nedokázal spustiť požadovaný komponent.\n\nProsím, aktualizujte na najnovšiu verziu aplikácie a skúste to znova.</string>
<plurals name="expiry_warning">
<item quantity="one">Toto je testovacia verzia aplikácie Briar. Platnosť vášho účtu vyprší o %d deň a nie je možné ho obnoviť.</item>
<item quantity="few">Toto je testovacia verzia aplikácie Briar. Platnosť vášho účtu vyprší o %d dni a nie je možné ho obnoviť.</item>
<item quantity="many">Toto je testovacia verzia aplikácie Briar. Platnosť vášho účtu vyprší o %d dní a nie je možné ho obnoviť.</item>
<item quantity="other">Toto je testovacia verzia aplikácie Briar. Platnosť vášho účtu vyprší o %d dní a nie je možné ho obnoviť.</item>
</plurals>
<plurals name="old_android_expiry_warning">
<item quantity="one">Systém Android 4 už nie je podporovaný. Briar prestane fungovať na %s (za %d deň). Nainštalujte si Briar na novšie zariadenie a vytvorte si nový účet.</item>
<item quantity="few">Systém Android 4 už nie je podporovaný. Briar prestane fungovať na %s (za %d dni). Nainštalujte si Briar na novšie zariadenie a vytvorte si nový účet.</item>
<item quantity="many">Systém Android 4 už nie je podporovaný. Briar prestane fungovať na %s (za %d dní). Nainštalujte si Briar na novšie zariadenie a vytvorte si nový účet.</item>
<item quantity="other">Systém Android 4 už nie je podporovaný. Briar prestane fungovať na %s (za %d dní). Nainštalujte si Briar na novšie zariadenie a vytvorte si nový účet.</item>
</plurals>
<string name="expiry_date_reached">Platnosť tohto softvéru vypršala.\nĎakujeme za testovanie!</string>
<string name="download_briar">Ak chcete pokračovať v používaní aplikácie Briar, stiahnite si najnovšiu verziu.</string>
<string name="create_new_account">Budete si musieť vytvoriť nový účet, ale môžete použiť rovnakú prezývku.</string>
<string name="download_briar_button">Stiahnite si najnovšiu verziu</string>
<string name="old_android_expiry_date_reached">Briar už nefunguje na systéme Android 4.\nProsím, nainštalujte Briar na novšie zariadenie.</string>
<string name="old_android_delete_account">Ťuknutím na tlačidlo nižšie môžete odstrániť svoje konto z tohto zariadenia.</string>
<string name="delete_account_button">Vymazať účet</string>
<string name="startup_open_database">Dešifrovanie databázy...</string>
<string name="startup_migrate_database">Aktualizácia databázy...</string>
<string name="startup_compact_database">Komprimovanie databázy...</string>
<!--Navigation Drawer-->
<string name="nav_drawer_open_description">Otvoriť navigačnú lištu</string>
<string name="nav_drawer_close_description">Zavrieť navigačnú lištu</string>
<string name="contact_list_button">Kontakty</string>
<string name="groups_button">Súkromné skupiny</string>
<string name="forums_button">Fóra</string>
<string name="blogs_button">Blogy</string>
<!--This is part of the main menu. The app will be locked when this is tapped.-->
<string name="lock_button">Zamknúť aplikáciu</string>
<string name="settings_button">Nastavenia</string>
<string name="sign_out_button">Odhlásiť sa</string>
<string name="transports_onboarding_text">Ťuknutím sem môžete ovládať, ako sa Briar pripája k vašim kontaktom.</string>
<!--Transports: Tor-->
<string name="transport_tor">Internet</string>
<string name="tor_device_status_online_wifi">Váš telefón má prístup na internet cez Wi-Fi</string>
<string name="tor_device_status_online_mobile">Váš telefón má prístup na internet cez mobilné dáta</string>
<string name="tor_device_status_offline">Váš telefón nemá prístup na internet</string>
<string name="tor_plugin_status_enabling">Briar sa pripája na internet</string>
<string name="tor_plugin_status_active">Briar sa pripojený na internet</string>
<string name="tor_plugin_status_inactive">Briar sa nemôže pripojiť na internet</string>
<string name="tor_plugin_status_disabled">Briar je nastavený tak, aby nepoužíval internet</string>
<string name="tor_plugin_status_disabled_mobile_data">Briar je nastavený tak, aby nepoužíval mobilné dáta</string>
<string name="tor_plugin_status_disabled_battery">Briar je nastavený tak, aby nepoužíval internet, keď ide na batériu</string>
<string name="tor_plugin_status_disabled_country_blocked">Briar je nastavený tak, aby v tejto krajine nepoužíval internet</string>
<!--Transports: Wi-Fi-->
<string name="transport_lan">Wi-Fi</string>
<string name="transport_lan_long">Rovnaká sieť Wi-Fi</string>
<string name="lan_device_status_on">Váš telefón je pripojený k sieti Wi-Fi</string>
<string name="lan_device_status_off">Váš telefón nie je pripojený k sieti Wi-Fi</string>
<string name="lan_plugin_status_enabling">Briar sa pripája k sieti Wi-Fi</string>
<string name="lan_plugin_status_active">Briar je pripojený k sieti Wi-Fi</string>
<string name="lan_plugin_status_inactive">Briar sa nemôže pripojiť k sieti Wi-Fi</string>
<string name="lan_plugin_status_disabled">Briar je nastavený tak, aby nepoužíval sieť Wi-Fi</string>
<!--Transports: Bluetooth-->
<string name="transport_bt">Bluetooth</string>
<string name="bt_device_status_on">Váš telefón má zapnuté Bluetooth</string>
<string name="bt_device_status_off">Váš telefón má vypnuté Bluetooth</string>
<string name="bt_plugin_status_enabling">Briar sa pripája cez Bluetooth</string>
<string name="bt_plugin_status_active">Briar je pripojený cez Bluetooth</string>
<string name="bt_plugin_status_inactive">Briar sa nedokáže pripojiť k Bluetooth</string>
<string name="bt_plugin_status_disabled">Briar je nastavený tak, aby nepoužíval Bluetooth</string>
<!--Notifications-->
<string name="reminder_notification_title">Odhlásený z aplikácie Briar</string>
<string name="reminder_notification_text">Ťuknutím sa prihláste späť.</string>
<string name="reminder_notification_channel_title">Pripomienka prihlásenia do aplikácie Briar</string>
<string name="reminder_notification_dismiss">Odmietnuť</string>
<string name="ongoing_notification_title">Prihlásený do Briar</string>
<string name="ongoing_notification_text">Dotknutím sa otvorte Briar.</string>
<plurals name="private_message_notification_text">
<item quantity="one">Nová súkromná správa</item>
<item quantity="few">%d nové súkromné správy</item>
<item quantity="many">%d nových súkromných správ</item>
<item quantity="other">%d nových súkromných správ</item>
</plurals>
<plurals name="group_message_notification_text">
<item quantity="one">Nová skupinová správa.</item>
<item quantity="few">%d nové skupinové správy.</item>
<item quantity="many">%d nových skupinových správ.</item>
<item quantity="other">%d nových skupinových správ.</item>
</plurals>
<plurals name="forum_post_notification_text">
<item quantity="one">Nový príspevok na fóre.</item>
<item quantity="few">%d nové príspevky na fóre.</item>
<item quantity="many">%d nových príspevkov na fóre.</item>
<item quantity="other">%d nových príspevkov na fóre.</item>
</plurals>
<plurals name="blog_post_notification_text">
<item quantity="one">Nový príspevok na blogu.</item>
<item quantity="few">%d nové príspevky na blogu.</item>
<item quantity="many">%d nových príspevkov na blogu.</item>
<item quantity="other">%d nových príspevkov na blogu.</item>
</plurals>
<!--Misc-->
<string name="now">teraz</string>
<string name="show">Zobraziť</string>
<string name="hide">Skryť</string>
<string name="ok">OK</string>
<string name="cancel">Zrušiť</string>
<string name="got_it">Rozumiem</string>
<string name="delete">Odstrániť</string>
<string name="accept">Prijať</string>
<string name="decline">Odmietnuť</string>
<string name="online">Pripojený</string>
<string name="offline">Odpojený</string>
<string name="send">Odoslať</string>
<string name="allow">Povoliť</string>
<string name="open">Otvoriť</string>
<string name="change">Zmeniť</string>
<string name="start">Spustiť</string>
<string name="finish">Dokončiť</string>
<string name="no_data">Žiadne údaje</string>
<string name="ellipsis"></string>
<string name="text_too_long">Zadaný text je príliš dlhý</string>
<string name="show_onboarding">Zobraziť dialógové okno pomocníka</string>
<string name="fix">Opraviť</string>
<string name="help">Pomoc</string>
<string name="sorry">Prepáčte</string>
<string name="error_start_activity">Vo vašom systéme nie je dostupné</string>
<string name="status_heading">Stav:</string>
<string name="error">Chyba</string>
<string name="info">Informácie</string>
<!--Contacts and Private Conversations-->
<string name="no_contacts">Žiadne kontakty na zobrazenie</string>
<string name="no_contacts_action">Ťuknutím na ikonu + pridáte kontakt</string>
<string name="date_no_private_messages">Žiadne správy.</string>
<string name="no_private_messages">Žiadne správy na zobrazenie</string>
<string name="message_hint">Nová správa</string>
<string name="message_hint_auto_delete">Nová miznúca správa</string>
<string name="message_error">Chyba pri odosielaní správy</string>
<string name="image_caption_hint">Pridať popis (nepovinné)</string>
<string name="image_attach">Priložiť obrázok</string>
<string name="image_attach_error">Nepodarilo sa pripojiť obrázok(ky)</string>
<string name="image_attach_error_too_big">Príliš veľký obrázok. Limit je %d MB.</string>
<string name="image_attach_error_invalid_mime_type">Formát obrázka nie je podporovaný: %s</string>
<string name="set_contact_alias">Zmeniť meno kontaktu</string>
<string name="set_contact_alias_hint">Meno kontaktu</string>
<string name="menu_item_disappearing_messages">Miznúce správy</string>
<!--The first placeholder will show a duration like "7 days". The second placeholder at the end will add "Tap to learn more."-->
<string name="auto_delete_msg_you_enabled">Vaše správy zmiznú po %1$s. %2$s </string>
<!--The placeholder at the end will add "Tap to learn more."-->
<string name="auto_delete_msg_you_disabled">Vaše správy nezmiznú. %1$s</string>
<!--The first placeholder will show a contact's name. The second placeholder will show a duration like "7 days". The third placeholder at the end will add "Tap to learn more."-->
<string name="auto_delete_msg_contact_enabled">Správy používateľa %1$szmiznú po %2$s. %3$s</string>
<plurals name="duration_minutes">
<item quantity="one">%d minúta</item>
<item quantity="few">%d minúty</item>
<item quantity="many">%d minút</item>
<item quantity="other">%d minút</item>
</plurals>
<plurals name="duration_hours">
<item quantity="one">%d hodina</item>
<item quantity="few">%d hodiny</item>
<item quantity="many">%d hodín</item>
<item quantity="other">%d hodín</item>
</plurals>
<plurals name="duration_days">
<item quantity="one">%d deň</item>
<item quantity="few">%d dni</item>
<item quantity="many">%d dní</item>
<item quantity="other">%d dní</item>
</plurals>
<!--The first placeholder will show a contact's name. The second placeholder at the end will add "Tap to learn more."-->
<string name="auto_delete_msg_contact_disabled">Správy používateľa %1$snezmiznú. %2$s</string>
<string name="tap_to_learn_more">Ťuknutím sa dozviete viac.</string>
<string name="auto_delete_changed_warning_title">Miznúce správy sa zmenili</string>
<string name="auto_delete_changed_warning_message_enabled">Odkedy ste začali písať správu, miznúce správy boli zapnuté.</string>
<string name="auto_delete_changed_warning_message_disabled">Odkedy ste začali písať správu, miznúce správy boli vypnuté.</string>
<string name="auto_delete_changed_warning_send">Odoslať aj tak</string>
<string name="delete_all_messages">Odstrániť všetky správy</string>
<string name="dialog_title_delete_all_messages">Potvrdiť odstránenie správy</string>
<string name="dialog_message_delete_all_messages">Ste si istí, že chcete odstrániť všetky správy?</string>
<string name="dialog_title_not_all_messages_deleted">Nepodarilo sa vymazať všetky správy</string>
<string name="dialog_message_not_deleted_ongoing_both">Správy týkajúce sa prebiehajúcich pozvaní a zoznámení nie je možné vymazať až do ich ukončenia.</string>
<string name="dialog_message_not_deleted_ongoing_introductions">Správy súvisiace s prebiehajúcimi zoznámeniami nie je možné vymazať, kým sa neukončia.</string>
<string name="dialog_message_not_deleted_ongoing_invitations">Správy súvisiace s prebiehajúcimi pozvaniami nie je možné vymazať, kým sa neukončia.</string>
<string name="dialog_message_not_deleted_not_all_selected_both">Ak chcete odstrániť pozvanie alebo zoznámenie, musíte vybrať žiadosť a odpoveď.</string>
<string name="dialog_message_not_deleted_not_all_selected_introductions">Ak chcete odstrániť zoznámenie, musíte vybrať žiadosť a odpoveď.</string>
<string name="dialog_message_not_deleted_not_all_selected_invitations">Ak chcete odstrániť pozvanie, musíte vybrať žiadosť a odpoveď.</string>
<string name="delete_contact">Odstrániť kontakt</string>
<string name="dialog_title_delete_contact">Potvrdiť odstránenie kontaktu</string>
<string name="dialog_message_delete_contact">Ste si istí, že chcete odstrániť tento kontakt a všetky správy vymenené s týmto kontaktom?</string>
<string name="contact_deleted_toast">Kontakt bol odstránený</string>
<!--This is shown in the action bar when opening an image in fullscreen that the user sent-->
<string name="you">Vy</string>
<string name="save_image">Uložiť obrázok</string>
<string name="dialog_title_save_image">Uložiť obrázok?</string>
<string name="dialog_message_save_image">Uloženie tohto obrázka umožní ostatným aplikáciám k jeho prístupu.\n\nSte si istí, že ho chcete uložiť?</string>
<string name="save_image_success">Obrázok bol uložený</string>
<string name="save_image_error">Obrázok sa nepodarilo uložiť</string>
<string name="dialog_title_no_image_support">Obrázky nie sú dostupné</string>
<string name="dialog_message_no_image_support">Aplikácia Briar vášho kontaktu zatiaľ nepodporuje obrázkové prílohy. Po ich aktualizácii sa vám zobrazí iná ikona.</string>
<string name="dialog_title_image_support">Tomuto kontaktu môžete teraz posielať obrázky</string>
<string name="dialog_message_image_support">Ťuknutím na túto ikonu pripojíte obrázky.</string>
<string name="messaging_too_many_attachments_toast">Odošle sa len prvých %d obrázkov</string>
<string name="menu_contact">Kontakt</string>
<!--Adding Contacts-->
<string name="add_contact_title">Pridať kontakt v blízkosti</string>
<string name="add_contact_error_two_way">Naskenovali ste si navzájom QR kódy?</string>
<string name="face_to_face">S osobou, ktorú chcete pridať ako kontakt sa musíte sa stretnúť osobne.\n\nTým sa zabráni tomu, aby sa niekto za vás vydával alebo čítal vaše správy v budúcnosti.</string>
<string name="continue_button">Pokračovať</string>
<string name="try_again_button">Skúsiť znova</string>
<string name="waiting_for_contact_to_scan">Čaká sa, kým kontakt naskenuje a pripojí sa\u2026</string>
<string name="exchanging_contact_details">Výmena kontaktných údajov\u2026</string>
<string name="contact_added_toast">Kontakt pridaný: %s</string>
<string name="contact_already_exists">Kontakt %s už existuje</string>
<string name="contact_already_exists_general">Kontakt už existuje</string>
<string name="qr_code_invalid">QR kód nie je platný</string>
<string name="qr_code_too_old_1">QR kód, ktorý ste naskenovali, pochádza zo staršej verzie aplikácie Briar.\n\nProsím, požiadajte svoj kontakt o aktualizáciu na najnovšiu verziu a potom to skúste znova.</string>
<string name="qr_code_too_new_1">QR kód, ktorý ste naskenovali, pochádza z novšej verzie aplikácie Briar.\n\nProsím, aktualizujte prosím na najnovšiu verziu a potom to skúste znova.</string>
<string name="mailbox_qr_code_for_contact">QR kód, ktorý ste naskenovali, pochádza z Briar Mailbox.\n\nAk chcete prepojiť Mailbox, vyberte prosím Nastavenia &gt; Mailbox z ponuky Briar.</string>
<string name="qr_code_format_unknown">QR kód, ktorý ste naskenovali, nie je určený na pridanie kontaktu Briar.\n\nNaskenujte QR kód zobrazený na obrazovke kontaktu.</string>
<string name="camera_error">Chyba kamery</string>
<string name="connecting_to_device">Pripájanie k zariadeniu\u2026</string>
<string name="authenticating_with_device">Overovanie so zariadením\u2026</string>
<string name="connection_error_title">Nepodarilo sa pripojiť k vášmu kontaktu</string>
<string name="connection_error_feedback">Ak tento problém pretrváva, pošlite nám prosím <a href="feedback">spätnú väzbu</a>, ktorá nám pomôže aplikáciu vylepšiť.</string>
<string name="info_both_must_scan">Obaja si musíte navzájom naskenovať QR kódy.</string>
<!--Adding Contacts Remotely-->
<string name="add_contact_remotely_title_case">Pridať vzdialený kontakt</string>
<string name="add_contact_nearby_title">Pridať kontakt v blízkosti</string>
<string name="add_contact_remotely_title">Pridať vzdialený kontakt </string>
<string name="contact_link_intro">Sem zadajte odkaz od vášho kontaktu</string>
<string name="contact_link_hint">Odkaz kontaktu</string>
<string name="paste_button">Vložiť</string>
<string name="add_contact_button">Pridať kontakt</string>
<string name="copy_button">Kopírovať</string>
<string name="share_button">Zdieľať</string>
<string name="send_link_title">Vymeniť odkazy</string>
<string name="add_contact_choose_nickname">Vybrať prezývku</string>
<string name="add_contact_choose_a_nickname">Zadajte prezývku</string>
<string name="nickname_intro">Dajte svojmu kontaktu prezývku. Len vy ju môžete vidieť.</string>
<string name="your_link">Poskytnite tento odkaz kontaktu, ktorý chcete pridať</string>
<string name="link_clip_label">Odkaz Briar</string>
<string name="link_copied_toast">Odkaz skopírovaný</string>
<string name="adding_contact_error">Pri pridávaní kontaktu došlo k chybe.</string>
<string name="pending_contact_requests_snackbar">Existujú čakajúce žiadosti o kontakt</string>
<string name="pending_contact_requests">Čakajúce žiadosti o kontakt</string>
<string name="no_pending_contacts">Žiadne čakajúce kontakty</string>
<string name="waiting_for_contact_to_come_online">Čaká sa na kontakt, kým sa pripojí online...</string>
<string name="connecting">Pripája sa…</string>
<string name="adding_contact">Pridávanie kontaktu...</string>
<string name="adding_contact_failed">Pridávanie kontaktu zlyhalo</string>
<string name="dialog_title_remove_pending_contact">Potvrdiť odstránenie</string>
<string name="dialog_message_remove_pending_contact">Tento kontakt sa stále pridáva. Ak ho teraz odstránite, nebude pridaný.</string>
<string name="own_link_error">Zadajte odkaz vášho kontaktu, nie svoj vlastný</string>
<string name="nickname_missing">Zadajte prosím prezývku</string>
<string name="invalid_link">Neplatný odkaz</string>
<string name="unsupported_link">Tento odkaz pochádza z novšej verzie aplikácie Briar. Prejdite na najnovšiu verziu a skúste to znova.</string>
<string name="intent_own_link">Otvorili ste svoj vlastný odkaz. Použite ten odkaz na kontakt, ktorý chcete pridať!</string>
<string name="missing_link">Prosím, zadajte odkaz</string>
<!--This is a numeral indicating the first step in a series of screens-->
<string name="step_1">1</string>
<!--This is a numeral indicating the second step in a series of screens-->
<string name="step_2">2</string>
<plurals name="contact_added_notification_text">
<item quantity="one">Nový kontakt pridaný.</item>
<item quantity="few">%dnové kontakty pridané.</item>
<item quantity="many">%dnových pridaných kontaktov.</item>
<item quantity="other">%dnových pridaných kontaktov.</item>
</plurals>
<string name="offline_state">Žiadne internetové pripojenie</string>
<string name="duplicate_link_dialog_title">Duplicitný odkaz</string>
<string name="duplicate_link_dialog_text_1">Už máte jeden čakajúci kontakt s týmto odkazom:: %s</string>
<string name="duplicate_link_dialog_text_1_contact">Už máte kontakt s týmto odkazom: %s</string>
<!--This is a question asking whether two nicknames refer to the same person-->
<string name="duplicate_link_dialog_text_2">Je %1$s a %2$stá istá osoba?</string>
<!--This is a button for answering that two nicknames do indeed refer to the same person. This
string will be used in a dialog button, so if the translation of this string is longer than 20
characters, please use "Yes" instead, and use "No" for the "Different Person" button-->
<string name="same_person_button">Tá istá osoba</string>
<!--This is a button for answering that two nicknames refer to different people. This string
will be used in a dialog button, so if the translation of this string longer than 20 characters,
please use "No" instead, and use "Yes" for the "Same Person" button-->
<string name="different_person_button">Iná osoba</string>
<string name="duplicate_link_dialog_text_3">%1$s a %2$s vám poslali rovnaký odkaz.\n\nJeden z nich sa možno snaží zistiť, kto sú vaše kontakty.\n\nNehovorte im, že ste dostali rovnaký odkaz od niekoho iného.</string>
<string name="pending_contact_updated_toast">Čakajúci kontakt bol aktualizovaný</string>
<string name="info_both_must_enter_links">Obaja si musíte navzájom pridať odkazy</string>
<!--Peer trust levels-->
<string name="peer_trust_level_unverified">Neoverený kontakt</string>
<string name="peer_trust_level_verified">Overený kontakt</string>
<string name="peer_trust_level_ourselves">Ja</string>
<string name="peer_trust_level_stranger">Cudzinec</string>
<!--Introductions-->
<string name="introduction_onboarding_title">Zoznámte svoje kontakty</string>
<string name="introduction_onboarding_text">Zoznámte svoje kontakty navzájom, aby sa mohli spojiť v aplikácii Briar.</string>
<string name="introduction_menu_item">Zoznámiť</string>
<string name="introduction_activity_title">Vybrať kontakt</string>
<string name="introduction_not_possible">S týmito kontaktmi už máte jedno zoznámenie za sebou. Prosím, umožnite, aby sa najskôr toto zoznámenie dokončilo. Ak ste vy alebo vaše kontakty zriedkakedy online, môže to chvíľu trvať.</string>
<string name="introduction_message_title">Zoznámiť kontakty</string>
<string name="introduction_message_hint">Pridať správu (nepovinné)</string>
<string name="introduction_button">Zoznámenie</string>
<string name="introduction_sent">Vaše zoznámenie bolo odoslané.</string>
<string name="introduction_error">Pri zoznamovaní došlo k chybe.</string>
<string name="introduction_request_sent">Požiadali ste o zoznámenie používateľa%1$s s%2$s.</string>
<string name="introduction_request_received">%1$s vás požiadal, aby ste sa zoznámili s %2$s. Chcete si pridať používateľa %2$sdo vášho zoznamu kontaktov?</string>
<string name="introduction_request_exists_received">%1$s vás požiadal, aby vás zoznámil s používateľom %2$s, ale %2$s je už vo vašom zozname kontaktov. Keďže %1$s o tom nemusí vedieť, stále môžete odpovedať:</string>
<string name="introduction_request_answered_received">%1$svás požiadal, aby ste zoznámili s %2$s.</string>
<string name="introduction_response_accepted_sent">Prijali ste zoznámenie s %1$s.</string>
<string name="introduction_response_accepted_sent_info">Predtým, ako bude %1$s pridaný do vašich kontaktov, musí zoznámenie prijať aj on. To môže nejaký čas trvať.</string>
<string name="introduction_response_declined_sent">Odmietli ste zoznámenie s %1$s.</string>
<string name="introduction_response_declined_auto">Zoznámenie s %1$s bolo automaticky odmietnuté.</string>
<string name="introduction_response_accepted_received">%1$sprijal/a zoznámenie s %2$s.</string>
<string name="introduction_response_declined_received">%1$sodmietol/a zoznámenie s %2$s.</string>
<string name="introduction_response_declined_received_by_introducee">%1$shovorí, že %2$sodmietol zoznámenie.</string>
<!--Connect via Bluetooth-->
<string name="menu_item_connect_via_bluetooth">Pripojiť cez Bluetooth</string>
<string name="connect_via_bluetooth_title">Pripojiť cez Bluetooth</string>
<string name="connect_via_bluetooth_intro">V prípade, že pripojenie Bluetooth nefunguje automaticky, môžete sa pomocou tejto obrazovky pripojiť manuálne.\n\nAby to fungovalo, váš kontakt musí byť nablízku.\n\nVy a váš kontakt by ste mali stlačiť \"Štart\" súčasne.</string>
<string name="connect_via_bluetooth_already_discovering">Už sa pokúšate pripojiť cez Bluetooth. Skús to prosím čoskoro znova.</string>
<string name="connect_via_bluetooth_no_location_permission">Nie je možné pokračovať bez povolenia určenia polohy</string>
<string name="connect_via_bluetooth_no_bluetooth_permission">Nie je možné pokračovať bez povolenia blízkych zariadení</string>
<string name="connect_via_bluetooth_start">Pripájanie cez Bluetooth…</string>
<string name="connect_via_bluetooth_success">Úspešne pripojené cez Bluetooth</string>
<string name="connect_via_bluetooth_error">Nepodarilo sa pripojiť cez Bluetooth.</string>
<string name="connect_via_bluetooth_error_not_supported">Bluetooth nie je podporovaný na tomto zariadením.</string>
<!--Private Groups-->
<string name="groups_list_empty">Žiadne skupiny na zobrazenie</string>
<string name="groups_list_empty_action">Ťuknutím na ikonu + vytvorte skupinu alebo požiadajte svoje kontakty, aby s vami zdieľali skupiny</string>
<string name="groups_created_by">Vytvoril používateľ %s</string>
<plurals name="messages">
<item quantity="one">%d správa</item>
<item quantity="few">%d správy</item>
<item quantity="many">%d správ</item>
<item quantity="other">%d správ</item>
</plurals>
<string name="groups_group_is_empty">Táto skupina je prázdna</string>
<string name="groups_group_is_dissolved">Táto skupina bola zrušená</string>
<string name="groups_remove">Odstrániť</string>
<string name="groups_create_group_title">Vytvoriť súkromnú skupinu</string>
<string name="groups_create_group_button">Vytvoriť skupinu</string>
<string name="groups_create_group_invitation_button">Poslať pozvánku</string>
<string name="groups_create_group_hint">Vyberte názov vašej súkromnej skupiny</string>
<string name="groups_invitation_sent">Skupinová pozvánka bola odoslaná</string>
<string name="groups_member_list">Zoznam členov</string>
<string name="groups_invite_members">Pozvať členov</string>
<string name="groups_member_created_you">Vytvorili ste skupinu</string>
<string name="groups_member_created">%s vytvoril/a skupinu</string>
<string name="groups_member_joined_you">Pripojili ste sa k skupine</string>
<string name="groups_member_joined">%s sa pripojil ku skupine</string>
<string name="groups_leave">Opustiť skupinu</string>
<string name="groups_leave_dialog_title">Potvrdiť opustenie skupiny</string>
<string name="groups_leave_dialog_message">Ste si istí, že chcete opustiť túto skupinu?</string>
<string name="groups_dissolve">Zrušiť skupinu</string>
<string name="groups_dissolve_dialog_title">Potvrdiť zrušenie skupiny</string>
<string name="groups_dissolve_dialog_message">Ste si istí, že chcete túto skupinu zrušiť?\n\nVšetci ostatní členovia nebudú môcť pokračovať v konverzácii a nemusia dostávať najnovšie správy.</string>
<string name="groups_dissolve_button">Zrušiť skupinu</string>
<string name="groups_dissolved_dialog_title">Skupina bola zrušená</string>
<string name="groups_dissolved_dialog_message">Zakladateľ tejto skupiny ju zrušil.\n\nUž nemôžete písať správy do skupiny a nemusíte dostávať všetky príspevky, ktoré boli napísané.</string>
<!--Private Group Invitations-->
<string name="groups_invitations_title">Skupinové pozvánky</string>
<string name="groups_invitations_invitation_sent">Pozvali ste používateľa %1$s skupiny \"%2$s\".</string>
<string name="groups_invitations_invitation_received">%1$svás pozval do skupiny \"%2$s\".</string>
<string name="groups_invitations_joined">Pripojený do skupiny</string>
<string name="groups_invitations_declined">Skupinové pozvanie odmietnuté</string>
<plurals name="groups_invitations_open">
<item quantity="one">%d otvorená pozvánka do skupiny</item>
<item quantity="few">%d otvorené pozvánky do skupiny</item>
<item quantity="many">%d otvorených pozvánok do skupiny</item>
<item quantity="other">%d otvorených pozvánok do skupiny</item>
</plurals>
<string name="groups_invitations_response_accepted_sent">Prijali ste pozvánku do skupiny od používateľa %s.</string>
<string name="groups_invitations_response_declined_sent">Odmietli ste pozvánku do skupiny od používateľa %s.</string>
<string name="groups_invitations_response_declined_auto">Pozvánka do skupiny od používateľa %sbola automaticky odmietnutá.</string>
<string name="groups_invitations_response_accepted_received">%sprijal/a pozvanie do skupiny.</string>
<string name="groups_invitations_response_declined_received">%s odmietol pozvanie do skupiny.</string>
<string name="sharing_status_groups">Do skupiny môže pozývať nových členov len jej zakladateľ. Nižšie sú uvedení všetci súčasní členovia skupiny.</string>
<!--Private Groups Revealing Contacts-->
<string name="groups_reveal_contacts">Odhaliť kontakty</string>
<string name="groups_reveal_dialog_message">Môžete si vybrať, či chcete odhaliť kontakty všetkým súčasným a budúcim členom tejto skupiny.\n\nOdhalenie kontaktov urýchľuje a zvyšuje spoľahlivosť vášho pripojenia k skupine, pretože s odhalenými kontaktmi môžete komunikovať, aj keď je tvorca skupiny offline.</string>
<string name="groups_reveal_visible">Vzťah s kontaktom je viditeľný pre skupinu</string>
<string name="groups_reveal_visible_revealed_by_us">Vzťah s kontaktom je viditeľný pre skupinu (odhalený vami)</string>
<string name="groups_reveal_visible_revealed_by_contact">Vzťah s kontaktom je viditeľný pre skupinu (odhalený používateľom %s )</string>
<string name="groups_reveal_invisible">Vzťah s kontaktom nie je viditeľný pre skupinu</string>
<!--Forums-->
<string name="no_forums">Žiadne fóra na zobrazenie</string>
<string name="no_forums_action">Ťuknutím na ikonu + vytvoríte fórum alebo požiadajte svoje kontakty, aby s vami zdieľali fóra</string>
<string name="create_forum_title">Vytvoriť fórum</string>
<string name="choose_forum_hint">Vyberte si názov pre vaše fórum</string>
<string name="create_forum_button">Vytvoriť fórum</string>
<string name="forum_created_toast">Fórum bolo vytvorené</string>
<string name="no_forum_posts">Žiadne články na zobrazenie</string>
<string name="no_posts">Žiadne príspevky</string>
<plurals name="posts">
<item quantity="one">%dpríspevok</item>
<item quantity="few">%dpríspevky</item>
<item quantity="many">%dpríspevkov</item>
<item quantity="other">%d príspevkov</item>
</plurals>
<string name="forum_new_message_hint">Nový príspevok</string>
<string name="forum_message_reply_hint">Nová odpoveď</string>
<string name="btn_reply">Odpovedať</string>
<string name="forum_leave">Opustiť fórum</string>
<string name="dialog_title_leave_forum">Potvrdiť opustenie fóra</string>
<string name="dialog_message_leave_forum">Ste si istí, že chcete opustiť toto fórum?\n\nVšetkým kontaktom, s ktorými ste zdieľali toto fórum, môžu prestať chodiť aktualizácie.</string>
<string name="dialog_button_leave">Odísť</string>
<string name="forum_left_toast">Opustené fórum</string>
<!--Forum Sharing-->
<string name="forum_share_button">Zdieľať fórum</string>
<string name="contacts_selected">Vybraté kontakty</string>
<string name="activity_share_toolbar_header">Vyberte kontakty</string>
<string name="no_contacts_selector">Žiadne kontakty na zobrazenie</string>
<string name="no_contacts_selector_action">Po pridaní kontaktu sa sem prosím vráťte</string>
<string name="forum_shared_snackbar">Fórum je zdieľané s vybranými kontaktmi</string>
<string name="forum_share_message">Pridať správu (nepovinné)</string>
<string name="forum_share_error">Pri zdieľaní tohto fóra došlo k chybe.</string>
<string name="forum_invitation_received">%1$s s vami zdieľa fórum \"%2$s\".</string>
<string name="forum_invitation_sent">Zdieľali ste fórum \"%1$s\" s používateľom %2$s.</string>
<string name="forum_invitations_title">Pozvánky na fórum</string>
<string name="forum_invitation_exists">Už ste prijali pozvánku do tohto fóra.\n\nPrijatím ďalších pozvánok sa vaše pripojenie k fóru zrýchli a bude spoľahlivejšie.</string>
<string name="forum_joined_toast">Pripojený do fóra</string>
<string name="forum_declined_toast">Pozvánka odmietnutá</string>
<string name="shared_by_format">Zdieľal používateľ %s</string>
<string name="forum_invitation_already_sharing">Už zdieľate</string>
<string name="forum_invitation_already_invited">Pozvánka už bola odoslaná</string>
<string name="forum_invitation_invite_received">Pozvánka už bola doručená</string>
<string name="forum_invitation_not_supported">Nie je podporované týmto kontaktom</string>
<string name="forum_invitation_error">Chyba. Toto je chyba a nie je to vaša chyba</string>
<string name="forum_invitation_response_accepted_sent">Prijali ste pozvanie do fóra od %s.</string>
<string name="forum_invitation_response_declined_sent">Odmietli ste pozvanie do fóra od %s.</string>
<string name="forum_invitation_response_declined_auto">Pozvánka do fóra od používateľa %s bola automaticky odmietnutá.</string>
<string name="forum_invitation_response_accepted_received">Používateľ %sprijal pozvanie do fóra.</string>
<string name="forum_invitation_response_declined_received">Používateľ %s odmietol pozvanie do fóra.</string>
<string name="sharing_status">Stav zdieľania</string>
<string name="sharing_status_forum">Každý člen fóra ho môže zdieľať so svojimi kontaktmi. Toto fórum zdieľate s nasledujúcimi kontaktmi. Môžu tam byť aj ďalší členovia, ktorých nevidíte.</string>
<string name="shared_with">Zdieľané s %1$d (%2$donline)</string>
<plurals name="forums_shared">
<item quantity="one">%d fórum zdieľané prostredníctvom kontaktov</item>
<item quantity="few">%d fóra zdieľané prostredníctvom kontaktov</item>
<item quantity="many">%d fór zdieľaných prostredníctvom kontaktov</item>
<item quantity="other">%d fór zdieľaných prostredníctvom kontaktov</item>
</plurals>
<string name="nobody">Nikto</string>
<!--Blogs-->
<string name="blogs_other_blog_empty_state">Žiadne články na zobrazenie</string>
<string name="read_more">čítať viac</string>
<string name="blogs_write_blog_post">Napísať príspevok do blogu</string>
<string name="blogs_write_blog_post_body_hint">Napíšte svoj príspevok na blog</string>
<string name="blogs_publish_blog_post">Zverejniť</string>
<string name="blogs_blog_post_created">Príspevok na blogu bol vytvorený</string>
<string name="blogs_blog_post_received">Prijatý nový príspevok na blogu</string>
<string name="blogs_blog_post_scroll_to">Prejsť na</string>
<string name="blogs_feed_empty_state">Žiadne články na zobrazenie</string>
<string name="blogs_feed_empty_state_action">Zobrazia sa tu príspevky od vašich kontaktov a blogov, ktoré odoberáte\n\nŤuknutím na ikonu pera napíšete príspevok.</string>
<string name="blogs_remove_blog">Odstrániť blog</string>
<string name="blogs_remove_blog_dialog_message">Ste si istí, že chcete odstrániť tento blog?\n\nPríspevky budú odstránené z vášho zariadenia, ale nie zo zariadení iných ľudí.\n\nVšetky kontakty, s ktorými ste zdieľali tento blog, môžu prestať dostávať aktualizácie.</string>
<string name="blogs_remove_blog_ok">Odstrániť</string>
<string name="blogs_blog_removed">Blog odstránený</string>
<string name="blogs_reblog_comment_hint">Pridať komentár (nepovinné)</string>
<string name="blogs_reblog_button">Zdieľať blog</string>
<!--Blog Sharing-->
<string name="blogs_sharing_share">Zdieľať blog</string>
<string name="blogs_sharing_error">Pri zdieľaní tohto blogu došlo k chybe.</string>
<string name="blogs_sharing_button">Zdieľať blog</string>
<string name="blogs_sharing_snackbar">Blog zdieľaný s vybranými kontaktmi</string>
<string name="blogs_sharing_response_accepted_sent">Prijali ste pozvanie na blog od %s.</string>
<string name="blogs_sharing_response_declined_sent">Odmietli ste pozvanie na blog od %s.</string>
<string name="blogs_sharing_response_declined_auto">Pozvánka na blog od používateľa %s bola automaticky odmietnutá.</string>
<string name="blogs_sharing_response_accepted_received">%s prijal pozvanie na blog.</string>
<string name="blogs_sharing_response_declined_received">%s odmietol pozvanie na blog.</string>
<string name="blogs_sharing_invitation_received">%1$szdieľal s vami blog \"%2$s\".</string>
<string name="blogs_sharing_invitation_sent">Zdieľali ste blog \"%1$s\" s používateľom%2$s.</string>
<string name="blogs_sharing_invitations_title">Pozvánky na blog</string>
<string name="blogs_sharing_joined_toast">Prihlásený na blog</string>
<string name="blogs_sharing_declined_toast">Pozvánka odmietnutá</string>
<string name="sharing_status_blog">Ktokoľvek, kto sa prihlási na odber blogu, ho môže zdieľať so svojimi kontaktmi. Tento blog zdieľate s nasledujúcimi kontaktmi. Môžu existovať aj ďalší odberatelia, ktorých nevidíte.</string>
<!--RSS Feeds-->
<string name="blogs_rss_feeds_import">Importovať RSS kanál</string>
<string name="blogs_rss_feeds_import_button">Importovať</string>
<string name="blogs_rss_feeds_import_hint">Zadajte adresu URL RSS kanálu</string>
<string name="blogs_rss_feeds_import_progress">Importovanie RSS kanála...</string>
<string name="blogs_rss_feeds_import_error">Je nám to ľúto! Pri importovaní vášho kanála došlo k chybe.</string>
<string name="blogs_rss_feeds_import_title">Importovať kanál zo súboru</string>
<string name="blogs_rss_feeds">Kanály RSS</string>
<string name="blogs_rss_feeds_manage_imported">Importované:</string>
<string name="blogs_rss_feeds_manage_author">Autor:</string>
<string name="blogs_rss_feeds_manage_updated">Naposledy aktualizované:</string>
<string name="blogs_rss_remove_feed">Odstrániť kanál</string>
<string name="blogs_rss_remove_feed_dialog_message">Ste si istí, že chcete odstrániť tento kanál?\n\nPríspevky budú odstránené z vášho zariadenia, ale nie zo zariadení iných ľudí.\n\nVšetky kontakty, s ktorými ste zdieľali tento kanál, môžu prestať dostávať aktualizácie.</string>
<string name="blogs_rss_remove_feed_ok">Odstrániť</string>
<string name="blogs_rss_feeds_manage_empty_state">Žiadne RSS kanály na zobrazenie\n\nŤuknutím na ikonu + naimportujte kanál</string>
<string name="blogs_rss_feeds_manage_error">Vyskytol sa problém s načítaním vašich kanálov. Skúste to prosím neskôr.</string>
<!--Settings Profile Picture-->
<string name="change_profile_picture">Ťuknutím zmeníte svoj profilový obrázok</string>
<string name="dialog_confirm_profile_picture_title">Zmeniť profilový obrázok</string>
<string name="dialog_confirm_profile_picture_remark">Iba vaše kontakty môžu vidieť tento obrázok </string>
<string name="change_profile_picture_failed_message">Je nám ľúto, ale pri aktualizácii vašej profilovej fotografie sa niečo pokazilo</string>
<!--Settings Display-->
<string name="pref_language_title">Jazyk a región</string>
<string name="pref_language_changed">Toto nastavenie sa prejaví po reštartovaní aplikácie Briar. Odhláste sa a reštartujte Briar.</string>
<string name="pref_language_default">Predvolené systémom</string>
<string name="display_settings_title">Zobrazenie</string>
<string name="pref_theme_title">Téma</string>
<string name="pref_theme_light">Svetlá</string>
<string name="pref_theme_dark">Tmavá</string>
<string name="pref_theme_auto">Automatická (podľa denného času)</string>
<string name="pref_theme_system">Predvolené systémom</string>
<!--Settings Connections-->
<string name="network_settings_title">Pripojenia</string>
<string name="bluetooth_setting">Prepojiť sa s kontaktmi cez Bluetooth</string>
<string name="wifi_setting">Prepojiť sa s kontaktmi v rovnakej sieti Wi-Fi</string>
<string name="tor_enable_title">Prepojiť sa s kontaktmi cez internet</string>
<string name="tor_enable_summary">Všetky pripojenia prechádzajú cez sieť Tor kvôli ochrane súkromia</string>
<string name="tor_network_setting">Spôsob pripojenia pre sieť Tor</string>
<string name="tor_network_setting_automatic">Automaticky podľa polohy</string>
<string name="tor_network_setting_without_bridges">Použiť sieť Tor bez premostenia</string>
<string name="tor_network_setting_with_bridges">Použiť sieť Tor s premostením</string>
<string name="tor_network_setting_never">Nepripájať sa k internetu</string>
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
<string name="tor_network_setting_summary">Automaticky: %1$s (v %2$s)</string>
<string name="tor_mobile_data_title">Použiť mobilné dáta</string>
<string name="tor_only_when_charging_title">Pripojiť sa k internetu len počas nabíjania</string>
<string name="tor_only_when_charging_summary">Zakáže pripojenie k internetu, keď zariadenie beží na batériu</string>
<!--Settings Security and Panic-->
<string name="security_settings_title">Bezpečnosť</string>
<string name="pref_lock_title">Zámok aplikácie</string>
<string name="pref_lock_summary">Použite zámok obrazovky zariadenia na ochranu aplikácie Briar, keď ste prihlásení</string>
<string name="pref_lock_disabled_summary">Ak chcete používať túto funkciu, nastavte pre svoje zariadenie zámok obrazovky.</string>
<string name="pref_lock_timeout_title">Časový limit nečinnosti zámku aplikácie</string>
<!--The %s placeholder is replaced with the following time spans, e.g. 5 Minutes, 1 Hour-->
<string name="pref_lock_timeout_summary">Ak nepoužívate program Briar, automaticky sa uzamkne po %s</string>
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
<string name="pref_lock_timeout_1">1 minúte</string>
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
<string name="pref_lock_timeout_5">5 minútach</string>
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
<string name="pref_lock_timeout_15">15 minútach</string>
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
<string name="pref_lock_timeout_30">30 minútach</string>
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
<string name="pref_lock_timeout_60">1 hodina</string>
<string name="pref_lock_timeout_never">Nikdy</string>
<string name="pref_lock_timeout_never_summary">Nikdy automaticky nezamykať Briar</string>
<string name="change_password">Zmeniť heslo</string>
<string name="current_password">Aktuálne heslo</string>
<string name="choose_new_password">Nové heslo</string>
<string name="confirm_new_password">Potvrdiť nové heslo</string>
<string name="password_changed">Heslo bolo zmenené.</string>
<string name="panic_setting">Nastavenie tlačidla paniky</string>
<string name="panic_setting_title">Tlačidlo Paniky</string>
<string name="panic_setting_hint">Nastavte, ako bude aplikácia Briar reagovať, keď použijete aplikáciu tlačidla paniky</string>
<string name="panic_app_setting_title">Aplikácia tlačidla paniky</string>
<string name="unknown_app">neznáma aplikácia</string>
<string name="panic_app_setting_summary">Žiadna aplikácia nebola nastavená</string>
<string name="panic_app_setting_none">Žiadne</string>
<string name="dialog_title_connect_panic_app">Potvrdiť aplikáciu paniky</string>
<string name="dialog_message_connect_panic_app">Ste si istí, že chcete povoliť aplikácii %1$sspustenie deštruktívnych akcií tlačidla paniky?</string>
<string name="panic_setting_destructive_action">Deštruktívne akcie</string>
<string name="panic_setting_signout_title">Odhlásiť sa</string>
<string name="panic_setting_signout_summary">Odhlásiť sa z Briaru, ak je stlačené tlačidlo pre paniku</string>
<string name="purge_setting_title">Vymazať účet</string>
<string name="purge_setting_summary">Vymazať svoje konto Briar pri stlačení tlačidla paniky. Pozor: Týmto sa natrvalo vymažú vaše identity, kontakty a správy</string>
<!--Settings Notifications-->
<string name="notification_settings_title">Oznámenia</string>
<string name="notify_sign_in_title">Pripomenúť mi, aby som sa prihlásil</string>
<string name="notify_sign_in_summary">Zobraziť pripomienku pri spustení telefónu alebo aktualizácii aplikácie</string>
<string name="notify_private_messages_setting_title">Súkromné správy</string>
<string name="notify_private_messages_setting_summary">Zobraziť upozornenia pre súkromné správy</string>
<string name="notify_private_messages_setting_summary_26">Nastaviť upozornenia pre súkromné správy</string>
<string name="notify_group_messages_setting_title">Skupinové správy</string>
<string name="notify_group_messages_setting_summary">Zobraziť upozornenia pre skupinové správy</string>
<string name="notify_group_messages_setting_summary_26">Nastaviť upozornenia pre skupinové správy</string>
<string name="notify_forum_posts_setting_title">Príspevky vo fóre</string>
<string name="notify_forum_posts_setting_summary">Zobraziť upozornenia na príspevky vo fóre</string>
<string name="notify_forum_posts_setting_summary_26">Nastaviť upozornenia na príspevky vo fóre</string>
<string name="notify_blog_posts_setting_title">Príspevky na blogu</string>
<string name="notify_blog_posts_setting_summary">Zobraziť upozornenia pre príspevky v blogu</string>
<string name="notify_blog_posts_setting_summary_26">Nastaviť upozornenia pre príspevky v blogu</string>
<string name="notify_vibration_setting">Vibrovať</string>
<string name="notify_sound_setting">Zvuk</string>
<string name="notify_sound_setting_default">Predvolené zvonenie</string>
<string name="notify_sound_setting_disabled">Žiadne</string>
<string name="choose_ringtone_title">Vybrať zvonenie</string>
<string name="cannot_load_ringtone">Nie je možné načítať zvonenie</string>
<!--Mailbox-->
<string name="mailbox_settings_title">Mailbox</string>
<string name="mailbox_setup_title">Nastavenie Mailbox</string>
<string name="mailbox_setup_intro">Aplikácia Mailbox umožňuje vašim kontaktom posielať správy, aj keď ste v režime offline. Schránka bude prijímať vaše správy a uchovávať ich, kým sa neobjavíte online.
\nAplikáciu Briar Mailbox môžete nainštalovať do náhradného zariadenia. Udržujte ho pripojené k napájaniu a Wi-Fi, aby bolo vždy online.</string>
<string name="mailbox_setup_download">Najprv nainštalujte aplikáciu Mailbox do iného zariadenia vyhľadaním \"Briar Mailbox\" v službe Google Play alebo kdekoľvek kde ste si stiahli Briar.\n
\nPotom prepojte svoj Mailbox s aplikáciou Briar naskenovaním QR kódu, ktorý zobrazí aplikácia Mailbox.</string>
<string name="mailbox_setup_download_link">Zdieľať odkaz na stiahnutie</string>
<string name="mailbox_setup_button_scan">Naskenovať kód QR aplikácie Mailbox</string>
<string name="permission_camera_qr_denied_body">Odmietli ste prístup ku kamere, ale skenovanie QR kódu vyžaduje použitie kamery.\n\nProsím, zvážte udelenie prístupu.</string>
<string name="mailbox_setup_connecting">Pripájanie na Mailbox...</string>
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
<string name="mailbox_setup_connecting_info">Toto môže trvať až %1s</string>
<string name="mailbox_qr_code_too_old">QR kód, ktorý ste naskenovali, pochádza zo staršej verzie aplikácie Briar Mailbox.\n\nProsím, aktualizujte Briar Mailbox na najnovšiu verziu a potom to skúste znova.</string>
<string name="mailbox_qr_code_too_new">QR kód, ktorý ste naskenovali, pochádza z novšej verzie aplikácie Briar Mailbox.\n\nProsím, aktualizujte Briar na najnovšiu verziu a potom to skúste znova.</string>
<string name="contact_qr_code_for_mailbox">Naskenovaný QR kód slúži na pridanie kontaktu Briar.\n\nAk chcete pridať kontakt, prejdite do zoznamu kontaktov a ťuknite na ikonu +.</string>
<string name="mailbox_setup_qr_code_wrong_description">QR kód, ktorý ste naskenovali, nepochádza z aplikácie Briar Mailbox.\n\nProsím, otvorte aplikáciu Briar Mailbox na svojom Mailbox zariadení a naskenujte QR kód, ktorý sa v nej nachádza.</string>
<string name="mailbox_setup_already_paired_title">Mailbox je už prepojený</string>
<string name="mailbox_setup_already_paired_description">Odpojte Mailbox na vašom druhom zariadení a skúste to znova.</string>
<string name="mailbox_setup_io_error_title">Nepodarilo sa pripojiť</string>
<string name="mailbox_setup_io_error_description">Skontrolujte, či sú obe zariadenia pripojené k internetu, a skúste to znova.</string>
<string name="mailbox_setup_assertion_error_title">Chyba aplikácie Mailbox</string>
<string name="mailbox_setup_assertion_error_description">Ak problém pretrváva, pošlite prosím spätnú väzbu (s anonymnými údajmi) prostredníctvom aplikácie Briar.</string>
<string name="mailbox_setup_camera_error_description">Nepodarilo sa získať prístup ku kamere. Skúste to znova, možno po reštartovaní zariadenia.</string>
<string name="mailbox_setup_paired_title">Pripojené</string>
<string name="mailbox_setup_paired_description">Vaša aplikácia Mailbox bola úspešne prepojená s Briar.\n
\nUdržujte svoju aplikáciu Mailbox pripojenú k napájaniu a Wi-Fi, aby bola vždy online.</string>
<string name="tor_offline_title">Odpojený</string>
<string name="tor_offline_description">Skontrolujte, či je toto zariadenie online a či je povolené pripojenie na internet.\n
\nPotom počkajte, kým sa ikona zemegule na obrazovke nastavení pripojenia zmení na zelenú.</string>
<string name="tor_offline_button_check">Skontrolovať nastavenia pripojenia</string>
<string name="mailbox_status_title">Stav aplikácie Mailbox</string>
<string name="mailbox_status_connected_title">Mailbox je spustený</string>
<string name="mailbox_status_problem_title">Briar má problémy s pripojením k Mailbox</string>
<string name="mailbox_status_failure_title">Mailbox nie je dostupný</string>
<string name="mailbox_status_app_too_old_title">Briar je príliš starý</string>
<string name="mailbox_status_app_too_old_message">Aktualizujte aplikáciu Briar na najnovšiu verziu a skúste to znova.</string>
<string name="mailbox_status_mailbox_too_old_title">Mailbox je príliš starý</string>
<string name="mailbox_status_mailbox_too_old_message">Aktualizujte aplikáciu Mailbox na najnovšiu verziu a skúste to znova.</string>
<string name="mailbox_status_check_button">Skontrolovať pripojenie</string>
<!--Example for string substitution: Last connection: 3min ago-->
<string name="mailbox_status_connected_info">Posledné pripojenie: %s</string>
<!--Indicates that there never was a connection to the mailbox. Last connection: Never-->
<string name="mailbox_status_connected_never">Nikdy</string>
<string name="mailbox_status_unlink_button">Odpojiť</string>
<string name="mailbox_status_unlink_dialog_title">Odpojiť Mailbox?</string>
<string name="mailbox_status_unlink_dialog_question">Ste si istí, že chcete zrušiť prepojenie s Mailbox?</string>
<string name="mailbox_status_unlink_dialog_warning">Ak zrušíte prepojenie s Mailbox, nebudete môcť prijímať správy, keď je Briar v režime offline.</string>
<string name="mailbox_status_unlink_no_wipe_title">Váš Mailbox bol odpojený</string>
<string name="mailbox_status_unlink_no_wipe_message">Keď budete mať nabudúce prístup k zariadeniu Mailbox, otvorte aplikáciu Mailbox a ťuknutím na tlačidlo \"Odpojiť\" dokončite proces.\n\nAk už nemáte prístup k zariadeniu Mailbox, neznepokojujte sa. Vaše údaje sú zašifrované, takže zostanú v bezpečí, aj keď proces nedokončíte.</string>
<string name="mailbox_status_unlink_success">Váš Mailbox bol odpojený</string>
<string name="mailbox_error_notification_channel_title">Briar Mailbox problém</string>
<string name="mailbox_error_notification_title">Briar Mailbox nie je dostupný</string>
<string name="mailbox_error_notification_text">Ťuknutím na položku opravte problém.</string>
<string name="mailbox_error_wizard_button">Opraviť problém</string>
<string name="mailbox_error_wizard_title">Sprievodca riešením problémov Mailbox</string>
<string name="mailbox_error_wizard_question1">Máte prístup k vášmu zariadeniu Mailbox?</string>
<string name="mailbox_error_wizard_answer1">Áno, mám k nemu prístup práve teraz.</string>
<string name="mailbox_error_wizard_answer2">Teraz nie, ale môžem k nemu získať prístup neskôr.</string>
<string name="mailbox_error_wizard_answer3">Nie, už k nemu nemám prístup.</string>
<string name="mailbox_error_wizard_info1_1">Skontrolujte, či je zariadenie Mailbox zapnuté a pripojené k internetu.</string>
<string name="mailbox_error_wizard_question1_1">Otvorte aplikáciu Mailbox. Čo vidíte?</string>
<string name="mailbox_error_wizard_answer1_1">Vidím pokyny na nastavenie aplikácie Mailbox</string>
<string name="mailbox_error_wizard_answer1_2">Vidím QR kód</string>
<string name="mailbox_error_wizard_answer1_3">Vidím \" Mailbox je spustený\"</string>
<string name="mailbox_error_wizard_answer1_4">Vidím \"Zariadenie je v režime offline\"</string>
<string name="mailbox_error_wizard_info1_1_1">Zrušte prosím prepojenie aplikácie Mailbox pomocou nižšie uvedeného tlačidla a potom postupujte podľa pokynov na zariadení Mailbox, aby ste ju opäť prepojili.</string>
<string name="mailbox_error_wizard_info_1_1_2">Zrušte prosím prepojenie aplikácie Mailbox pomocou tlačidla nižšie a potom naskenujte QR kód, aby ste ju opäť prepojili.</string>
<string name="mailbox_error_wizard_info1_1_3">Pomocou nasledujúceho tlačidla skontrolujte prosím pripojenie medzi aplikáciami Briar a Mailbox.\n\n
Ak spojenie opäť zlyhá:\n
\u2022 Skontrolujte, či sú aplikácie Mailbox a Briar aktualizované na najnovšiu verziu.\n
\u2022 Reštartujte svoje zariadenia Mailbox a Briar a skúste to znova.</string>
<string name="mailbox_error_wizard_info1_1_4">Skontrolujte, či je zariadenie Mailbox správne pripojené k internetu.\n\nPrekontrolujte, či hodiny na zariadení Mailbox ukazujú správny čas, dátum a časové pásmo.\n\nPrekontrolujte, či sú aplikácie Mailbox a Briar aktualizované na najnovšiu verziu.\n\nReštartujte zariadenia Mailbox a Briar a skúste to znova.</string>
<string name="mailbox_error_wizard_info2">Vráťte sa prosím späť na túto obrazovku, keď budete mať prístup k zariadeniu.</string>
<string name="mailbox_error_wizard_info3">Zrušte prosím prepojenie svojej aplikácie Mailbox pomocou tlačidla nižšie.\n\nPo zrušení prepojenia vašej starej aplikácie Mailbox môžete kedykoľvek nastaviť novú aplikáciu Mailbox.</string>
<!--About-->
<string name="about_title">O programe</string>
<string name="briar_version">Briar verzia: %s</string>
<string name="tor_version">Tor verzia: %s</string>
<string name="links">Odkazy</string>
<string name="briar_website">\u2022 <a href="">Webová stránka</a></string>
<string name="briar_source_code">\u2022 <a href="">Zdrojový kód</a></string>
<string name="briar_changelog">\u2022 <a href="">Zoznam zmien</a></string>
<string name="briar_privacy_policy">\u2022 <a href="">Zásady ochrany súkromia</a></string>
<!--Here translators can add their names or Transifex usernames(eg "Thanks to all the contributors at the Localization Lab, especially Tom, Matthew and Jerry")-->
<string name="translator_thanks">Ďakujeme všetkým prispievateľom z Localization Lab, hlavne prekladateľom: Jozef Gaál</string>
<!--Conversation Settings-->
<string name="disappearing_messages_title">Miznúce správy</string>
<string name="disappearing_messages_explanation_long">Zapnutím tohto nastavenia nové
správy v tejto konverzácii automaticky zmiznú po 7\u00A0dňoch.
\n\nOdpočet pre kópiu správy odosielateľa sa začne po jej doručení.
Odpočítavanie pre príjemcu sa začne po prečítaní správy.
\n\nSprávy, ktoré zmiznú sú označené ikonou bomby.
\n\nMajte na pamäti, že príjemcovia môžu stále vytvárať kópie správ, ktoré ste odoslali.
\n\nAk toto nastavenie zmeníte, bude sa okamžite vzťahovať na nové správy a na
správy kontaktov, keď dostanú vašu ďalšiu správu.
Váš kontakt môže toto nastavenie zmeniť aj pre vás oboch.</string>
<string name="learn_more">Zisti viac</string>
<string name="disappearing_messages_summary">Nastaviť, aby budúce správy v tejto konverzácii automaticky zmizli po 7\u00A0dňoch.</string>
<!--Settings Actions-->
<string name="pref_category_actions">Akcie</string>
<string name="send_feedback">Odoslať spätnú väzbu</string>
<!--Link Warning-->
<string name="link_warning_title">Varovanie o odkaze</string>
<string name="link_warning_intro">Chystáte sa otvoriť nasledujúci odkaz pomocou externej aplikácie.</string>
<string name="link_warning_text">Toto môže byť použité na vašu identifikáciu. Premyslite si, či dôverujete osobe, ktorá vám poslala tento odkaz, a zvážte jeho otvorenie pomocou prehliadača Tor.</string>
<string name="link_warning_open_link">Otvoriť odkaz</string>
<!--Crash Reporter-->
<string name="crash_report_title">Briar Hlásenie o chybe</string>
<string name="briar_crashed">Prepáčte, aplikácia Briar spadla</string>
<string name="not_your_fault">Toto nie je vaša chyba.</string>
<string name="please_send_report">Pomôžte nám prosím vytvoriť lepší Briar tým, že nám pošlete hlásenie o chybe.</string>
<string name="report_is_encrypted">Sľubujeme, že hlásenie bude zašifrované a odoslané bezpečne.</string>
<string name="feedback_title">Spätná väzba</string>
<string name="describe_crash">Opíšte, čo sa stalo (nepovinné)</string>
<string name="enter_feedback">Zadajte svoju spätnú väzbu</string>
<string name="optional_contact_email">Vaša e-mailová adresa (nepovinné)</string>
<string name="privacy_policy">Odoslaním údajov súhlasíte s našimi <a href="">zásadami ochrany osobných údajov</a></string>
<string name="include_debug_report_crash">Zahrnúť anonymné údaje o chybe</string>
<string name="include_debug_report_feedback">Zahrnúť anonymné údaje o tomto zariadení</string>
<string name="dev_report_user_info">Informácie o používateľovi</string>
<string name="dev_report_basic_info">Základné informácie</string>
<string name="dev_report_device_info">Informácie o zariadení</string>
<string name="dev_report_stacktrace">Trasovanie zásobníka</string>
<string name="dev_report_time_info">Informácie o čase</string>
<string name="dev_report_memory">Pamäť</string>
<string name="dev_report_storage">Úložný priestor</string>
<string name="dev_report_connectivity">Konektivita</string>
<string name="dev_report_network_usage">Využitie siete</string>
<string name="dev_report_build_config">Konfigurácia zostavy</string>
<string name="dev_report_logcat">Záznam aplikácie</string>
<string name="dev_report_device_features">Funkcie zariadenia</string>
<string name="send_report">Odoslať hlásenie</string>
<string name="close">Zavrieť</string>
<string name="dev_report_sending">Odosielanie spätnej väzby...</string>
<string name="dev_report_sent">Spätná väzba odoslaná</string>
<string name="dev_report_saved">Hlásenie bolo uložené. Odošle sa pri ďalšom prihlásení do aplikácie Briar.</string>
<string name="dev_report_error">Chyba: Odoslanie hlásenia zlyhalo</string>
<!--Sign Out-->
<string name="progress_title_logout">Odhlasovanie z Briar...</string>
<!--Screen Filters & Tapjacking-->
<string name="screen_filter_title">Rozpoznané prekrytie obrazovky</string>
<string name="screen_filter_body">Ďalšia aplikácia vykresľuje nad aplikáciou Briar. Na ochranu vašej bezpečnosti nebude Briar reagovať na dotyky, keď naň vykresľuje iná aplikácia.\n\nNasledujúce aplikácie môžu vykresľovať nad ňou:\n\n%1$s</string>
<string name="screen_filter_body_api_30">Iná aplikácia vykresľuje údaje nad aplikáciou Briar. Na ochranu vašej bezpečnosti nebude Briar reagovať na dotyky, keď naň vykresľuje iná aplikácia.\n\nPreskúmajte aplikácie nižšie uvedené a nájdite zodpovednú aplikáciu.</string>
<string name="screen_filter_allow">Povoliť týmto aplikáciám vykresľovanie nad aplikáciou</string>
<string name="screen_filter_review_apps">Preskúmať aplikácie</string>
<!--Permission Requests-->
<string name="permission_camera_title">Povolenie na používanie kamery</string>
<string name="permission_camera_request_body">Na naskenovanie QR kódu potrebuje Briar prístup ku kamere.</string>
<string name="permission_location_title">Povolenie na určenie polohy</string>
<string name="permission_location_request_body">Na zistenie zariadení Bluetooth potrebuje Briar povolenie na prístup k vašej polohe.\n\nBriar neukladá vašu polohu ani ju s nikým nezdieľa.</string>
<string name="permission_camera_location_title">Kamera a poloha</string>
<string name="permission_camera_location_request_body">Na skenovanie QR kódu potrebuje Briar prístup ku kamere.\n\nNa zistenie zariadení Bluetooth potrebuje Briar povolenie na prístup k vašej polohe.\n\nBriar neukladá vašu polohu ani ju s nikým nezdieľa.</string>
<string name="permission_camera_bluetooth_title">Kamera a blízke zariadenia</string>
<string name="permission_camera_bluetooth_request_body">Na skenovanie QR kódu potrebuje Briar prístup ku kamere.\n\nNa zisťovanie zariadení Bluetooth potrebuje Briar povolenie na vyhľadanie a pripojenie k blízkym zariadeniam.</string>
<string name="permission_camera_denied_body">Odmietli ste prístup k fotoaparátu, ale pridávanie kontaktov vyžaduje používanie fotoaparátu.\n\nProsím, zvážte udelenie prístupu.</string>
<string name="permission_location_denied_body">Odmietli ste prístup k vašej polohe, ale Briar potrebuje toto povolenie na zistenie zariadení Bluetooth.\n\nProsím, zvážte udelenie prístupu.</string>
<string name="permission_location_setting_title">Nastavenie polohy</string>
<string name="permission_location_setting_body">Nastavenie polohy vášho zariadenia musí byť zapnuté, aby ste mohli nájsť iné zariadenia prostredníctvom Bluetooth. Ak chcete pokračovať, povoľte určovanie polohy. Neskôr ho môžete opäť vypnúť.</string>
<string name="permission_location_setting_hotspot_body">Ak chcete vytvoriť prístupový bod Wi-Fi, musí byť v zariadení zapnuté nastavenie polohy. Ak chcete pokračovať, povoľte určovanie polohy. Neskôr ho môžete opäť zakázať.</string>
<string name="permission_location_setting_button">Zapnúť polohu</string>
<string name="permission_bluetooth_title">Povolenie pre blízke zariadenia</string>
<string name="permission_bluetooth_body">Na používanie komunikácie Bluetooth potrebuje zariadenie Briar povolenie na vyhľadávanie a pripojenie k blízkym zariadeniam.</string>
<string name="permission_bluetooth_denied_body">Odmietli ste prístup k blízkym zariadeniam, ale Briar potrebuje toto povolenie na používanie Bluetooth.\n\nProsím, zvážte udelenie prístupu.</string>
<string name="qr_code">QR kód</string>
<string name="show_qr_code_fullscreen">Zobraziť QR kód na celú obrazovku</string>
<!--App Locking-->
<string name="lock_unlock">Odomknúť Briar</string>
<string name="lock_unlock_verbose">Na odomknutie zariadenia Briar zadajte PIN, vzor alebo heslo.</string>
<string name="lock_unlock_fingerprint_description">Dotknite sa snímača odtlačkov prstov registrovaným prstom a pokračujte</string>
<string name="lock_unlock_password">Použiť heslo</string>
<string name="lock_is_locked">Briar je zamknutý</string>
<string name="lock_tap_to_unlock">Ťuknutím odomknite</string>
<!--Connections Screen-->
<string name="transports_help_text">Briar sa môže pripojiť ku kontaktom cez internet, Wi-Fi alebo Bluetooth.\n\nVšetky internetové pripojenia prechádzajú cez sieť Tor kvôli ochrane súkromia.\n\nAk sa kontakt dá dosiahnuť viacerými spôsobmi, Briar ich bude používať paralelne.</string>
<!--Share app offline-->
<string name="hotspot_title">Zdieľať túto aplikáciu v režime offline</string>
<string name="hotspot_intro">Zdieľajte túto aplikáciu s niekým v okolí bez pripojenia na internet pomocou Wi-Fi v telefóne.
\n\nVáš telefón spustí prístupový bod Wi-Fi. Ľudia v blízkosti sa budú môcť pripojiť k prístupovému bodu a stiahnuť si aplikáciu Briar z vášho telefónu.</string>
<string name="hotspot_button_start_sharing">Spustiť prístupový bod</string>
<string name="hotspot_button_stop_sharing">Zastaviť prístupový bod</string>
<string name="hotspot_progress_text_start">Nastavovanie prístupového bodu...</string>
<string name="hotspot_notification_channel_title">Prístupový bod Wi-Fi</string>
<string name="hotspot_notification_title">Zdieľanie aplikácie Briar v režime offline</string>
<string name="hotspot_button_connected">Ďalej</string>
<string name="permission_hotspot_location_request_body">Na vytvorenie prístupového bodu Wi-Fi potrebuje Briar povolenie na prístup k vašej polohe.\n\nBriar neukladá vašu polohu ani ju s nikým nezdieľa.</string>
<string name="permission_hotspot_location_request_precise_body">Na vytvorenie prístupového bodu Wi-Fi potrebuje Briar povolenie na prístup k vašej presnej polohe.\n\nBriar neukladá vašu polohu ani ju s nikým nezdieľa.</string>
<string name="permission_hotspot_location_denied_body">Odmietli ste prístup k svojej polohe, ale Briar potrebuje toto povolenie na vytvorenie prístupového bodu Wi-Fi.\n\nProsím, zvážte udelenie prístupu.</string>
<string name="permission_hotspot_location_denied_precise_body">Odmietli ste prístup k presnej polohe, ale Briar potrebuje toto povolenie na vytvorenie prístupového bodu Wi-Fi.\n\nProsím, zvážte udelenie prístupu.</string>
<string name="wifi_settings_title">Nastavenie Wi-Fi</string>
<string name="wifi_settings_request_enable_body">Ak chcete vytvoriť prístupový bod Wi-Fi, zariadenie Briar musí používať Wi-Fi. Povoľte ho.</string>
<string name="hotspot_tab_manual">Manuálne</string>
<!--The placeholder to be inserted into the string 'hotspot_manual_wifi': People can connect by %s-->
<string name="hotspot_scanning_a_qr_code">naskenovaním QR kódu</string>
<!--Wi-Fi setup-->
<!--The %s placeholder will be replaced with the translation of 'hotspot_scanning_a_qr_code'-->
<string name="hotspot_manual_wifi">Váš telefón poskytuje prístupový bod Wi-Fi. Ľudia, ktorí si chcú stiahnuť Briar, sa môžu pripojiť k vášmu prístupovému bodu pridaním nižšie uvedených údajov do nastavení Wi-Fi svojho zariadenia alebo pomocou %s. Po ich pripojení k prístupovému bodu stlačte tlačidlo \"Ďalej\".</string>
<string name="hotspot_manual_wifi_ssid">Názov siete</string>
<string name="hotspot_qr_wifi">Váš telefón poskytuje prístupový bod Wi-Fi. Ľudia, ktorí si chcú stiahnuť program Briar, sa môžu pripojiť k prístupovému bodu naskenovaním tohto QR kódu. Po ich pripojení k prístupovému bodu stlačte tlačidlo \'Ďalej\'.</string>
<string name="hotspot_no_peers_connected">Žiadne pripojené zariadenia</string>
<plurals name="hotspot_peers_connected">
<item quantity="one">%spripojené zariadenie</item>
<item quantity="few">%spripojené zariadenia</item>
<item quantity="many">%spripojených zariadení</item>
<item quantity="other">%spripojených zariadení</item>
</plurals>
<!--Download link-->
<!--The %s placeholder will be replaced with the translation of 'hotspot_scanning_a_qr_code'-->
<string name="hotspot_manual_site">Váš telefón poskytuje prístupový bod Wi-Fi. Ľudia, ktorí sú pripojení k prístupovému bodu, si môžu stiahnuť aplikáciu Briar zadaním nasledujúceho odkazu do webového prehliadača alebo %s.</string>
<string name="hotspot_manual_site_address">Adresa (URL)</string>
<string name="hotspot_qr_site">Váš telefón poskytuje prístupový bod Wi-Fi. Ľudia, ktorí sú pripojení k prístupovému bodu, si môžu stiahnuť Briar naskenovaním tohto QR kódu.</string>
<!--e.g. Download Briar 1.2.20-->
<string name="website_download_title_1">Stiahnuť Briar %s</string>
<string name="website_download_intro_1">Niekto v okolí s vami zdieľa Briar.</string>
<string name="website_download_button">Stiahnuť Briar</string>
<string name="website_download_outro">Po dokončení sťahovania otvorte stiahnutý súbor a nainštalujte ho.</string>
<string name="website_troubleshooting_title">Riešenie problémov</string>
<string name="website_troubleshooting_1">Ak sa vám aplikáciu nepodarí stiahnuť, skúste to pomocou inej aplikácie webového prehliadača.</string>
<string name="website_troubleshooting_2_old">Ak chcete nainštalovať prevzatú aplikáciu, možno budete musieť v nastaveniach systému povoliť inštaláciu aplikácií z \"Neznámych zdrojov\". Potom bude možno potrebné aplikáciu znova stiahnuť. Po nainštalovaní aplikácie odporúčame vypnúť nastavenie \"Neznáme zdroje\".</string>
<string name="website_troubleshooting_2_new">Ak chcete nainštalovať prevzatú aplikáciu, možno budete musieť prehliadaču povoliť inštaláciu neznámych aplikácií. Po nainštalovaní aplikácie odporúčame odstrániť povolenie prehliadača inštalovať neznáme aplikácie.</string>
<string name="hotspot_help_wifi_title">Problémy s pripojením k sieti Wi-Fi:</string>
<string name="hotspot_help_wifi_1">Skúste vypnúť a znova povoliť Wi-Fi na oboch telefónoch a skúste to znova.</string>
<string name="hotspot_help_wifi_2">Ak sa telefón sťažuje, že v sieti Wi-Fi nie je internet, povedzte mu, že aj tak chcete zostať pripojení.</string>
<string name="hotspot_help_wifi_3">Reštartujte telefón, v ktorom je spustený prístupový bod Wi-Fi, potom spustite aplikáciu Briar a skúste zdieľanie znova.</string>
<string name="hotspot_help_site_title">Problémy s návštevou miestnej webovej stránky:</string>
<string name="hotspot_help_site_1">Skontrolujte, či ste adresu zadali presne tak, ako je zobrazená. Aj malá chyba môže spôsobiť zlyhanie.</string>
<string name="hotspot_help_site_2">Pri pokuse o prístup na stránku sa uistite, že je telefón stále pripojený k správnej sieti Wi-Fi (pozrite vyššie).</string>
<string name="hotspot_help_site_3">Ak máte aplikáciu firewall, skontrolujte, či neblokuje prístup.</string>
<string name="hotspot_help_site_4">Ak môžete navštíviť stránku, ale nemôžete si stiahnuť aplikáciu Briar, skúste to pomocou inej aplikácie webového prehliadača.</string>
<string name="hotspot_help_fallback_title">Nič nefunguje?</string>
<string name="hotspot_help_fallback_intro">Môžete sa pokúsiť uložiť aplikáciu ako súbor .apk a zdieľať ju iným spôsobom. Po prenesení súboru do druhého zariadenia ho môžete použiť na inštaláciu aplikácie Briar.
\n\nTip: Pri zdieľaní cez Bluetooth bude možno potrebné najprv premenovať súbor tak, aby končil na .zip.</string>
<string name="hotspot_help_fallback_button">Uložiť aplikáciu</string>
<!--error handling-->
<string name="hotspot_error_intro">Pri pokuse o zdieľanie aplikácie cez Wi-Fi sa niečo pokazilo:</string>
<string name="hotspot_error_no_wifi_direct">Zariadenie nepodporuje funkciu Wi-Fi Direct</string>
<string name="hotspot_error_start_callback_failed">Prístupový bod sa nepodarilo spustiť: chyba %s</string>
<string name="hotspot_error_start_callback_failed_unknown">Prístupový bod sa nepodarilo spustiť s neznámej príčiny, dôvod %d</string>
<string name="hotspot_error_start_callback_no_group_info">Prístupový bod sa nepodarilo spustiť: žiadne informácie o skupine</string>
<string name="hotspot_error_web_server_start">Chyba pri spustení webového servera</string>
<string name="hotspot_error_web_server_serve">Chyba pri zobrazovaní webovej stránky.\n\nProsím, pošlite spätnú väzbu (s anonymnými údajmi) prostredníctvom aplikácie Briar, ak problém pretrváva.</string>
<string name="hotspot_flag_test">Varovanie: Táto aplikácia bola nainštalovaná pomocou aplikácie Android Studio a NIE je možné ju nainštalovať do iného zariadenia.</string>
<string name="hotspot_error_framework_busy">Prístupový bod sa nedá spustiť.\n\nAk máte spustený iný prístupový bod alebo zdieľate internetové pripojenie cez Wi-Fi, skúste ho zastaviť a potom to skúste znova.</string>
<!--Transfer Data via Removable Drives-->
<string name="removable_drive_menu_title">Pripojiť cez vymeniteľný disk</string>
<string name="removable_drive_intro">Ak sa nemôžete pripojiť ku kontaktu cez internet, Wi-Fi alebo Bluetooth, Briar dokáže prenášať správy aj na vymeniteľnom disku, ako je USB kľúč alebo SD karta.</string>
<string name="removable_drive_explanation">Ak sa nemôžete pripojiť ku kontaktu cez internet, Wi-Fi alebo Bluetooth, Briar dokáže prenášať správy aj na vymeniteľnom disku, ako je napríklad USB kľúč alebo SD karta.\n\nPri použití tlačidla \"Odoslať údaje\" sa všetky údaje, ktoré čakajú na odoslanie kontaktu, zapíšu na vymeniteľný disk. Patria sem súkromné správy, prílohy, blogy, fóra a súkromné skupiny.\n\nVšetko bude zašifrované pred zápisom na vymeniteľný disk.\n\nKeď váš kontakt dostane vymeniteľný disk, môže použiť tlačidlo \"Prijať údaje\" na import správ do aplikácie Briar.</string>
<string name="removable_drive_title_send">Odoslať údaje</string>
<string name="removable_drive_title_receive">Prijať údaje</string>
<string name="removable_drive_send_intro">Ťuknutím na tlačidlo nižšie vytvoríte nový súbor obsahujúci zašifrované správy. Môžete si vybrať, kam sa súbor uloží.\n\nAk chcete súbor uložiť na vymeniteľný disk, vložte ho teraz.</string>
<string name="removable_drive_send_no_data">V súčasnosti nie sú žiadne správy čakajúce na odoslanie tomuto kontaktu.</string>
<string name="removable_drive_send_not_supported">Tento kontakt používa starú verziu aplikácie Briar alebo staré zariadenie, ktoré túto funkciu nepodporuje.</string>
<string name="removable_drive_send_button">Výber súboru na exportovanie</string>
<string name="removable_drive_ongoing">Počkajte na dokončenie prebiehajúcej úlohy</string>
<string name="removable_drive_receive_intro">Ťuknite na tlačidlo nižšie a vyberte súbor, ktorý vám poslal váš kontakt.\n\nAk je súbor na vymeniteľnom disku, vložte ho teraz.</string>
<string name="removable_drive_receive_button">Vyberte súbor na importovanie</string>
<string name="removable_drive_success_send_title">Exportovanie bolo úspešné</string>
<string name="removable_drive_success_send_text">Údaje boli úspešne exportované. Teraz máte 28 dní na prenos súboru ku kontaktu.\n\nAk je súbor na vymeniteľnom disku, použite upozornenie v stavovom riadku, aby ste disk vysunuli pred jeho odpojením.</string>
<string name="removable_drive_success_receive_title">Nahrávanie bolo úspešné</string>
<string name="removable_drive_success_receive_text">Všetky zašifrované správy obsiahnuté v tomto súbore boli prijaté.</string>
<string name="removable_drive_error_send_title">Chyba pri exportovaní údajov</string>
<string name="removable_drive_error_send_text">Došlo k chybe pri zápise údajov do súboru.\n\nAk používate vymeniteľný disk, uistite sa, že je správne vložený a skúste to znova.\n\nAk chyba pretrváva, pošlite spätnú väzbu a informujte o probléme tím Briar.</string>
<string name="removable_drive_error_receive_title">Chyba pri importovaní údajov</string>
<string name="removable_drive_error_receive_text">Vybraný súbor neobsahoval nič, čo by Briar mohol rozpoznať.\n\nProsím, skontrolujte, či ste vybrali správny súbor.\n\nAk váš kontakt vytvoril súbor pred viac ako 28 dňami, Briar ho nebude môcť rozpoznať.</string>
<!--Screenshots-->
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
<string name="screenshot_alice">Alica</string>
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
<string name="screenshot_bob">Robo</string>
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
<string name="screenshot_carol">Karolína</string>
<!--This is a message to be used in screenshots. Please use the same translation for Bob!-->
<string name="screenshot_message_1">Ahoj, Robo!</string>
<!--This is a message to be used in screenshots. Please use the same translation for Alice!-->
<string name="screenshot_message_2">Ahoj Alica! Vďaka, že si mi povedala o Briar!</string>
<!--This is a message to be used in screenshots.-->
<string name="screenshot_message_3">Žiadny problém, dúfam, že sa ti páči 😀</string>
</resources>

View File

@@ -235,7 +235,6 @@ dhe smund të hapet me këtë version.\n\nJu lutemi, përmirësojeni me versi
<string name="exchanging_contact_details">Po shkëmbehen hollësi kontaktesh\u2026</string> <string name="exchanging_contact_details">Po shkëmbehen hollësi kontaktesh\u2026</string>
<string name="contact_added_toast">Kontakti u shtua: %s</string> <string name="contact_added_toast">Kontakti u shtua: %s</string>
<string name="contact_already_exists">Kontakti %s ekziston tashmë</string> <string name="contact_already_exists">Kontakti %s ekziston tashmë</string>
<string name="contact_already_exists_general">Kontakti ekziston tashmë</string>
<string name="qr_code_invalid">Kodi QR është i pavlefshëm</string> <string name="qr_code_invalid">Kodi QR është i pavlefshëm</string>
<string name="qr_code_too_old_1">Kodi QR që keni skanuar vjen prej një versioni të vjetër të Briar-it.\n\nJu lutemi, kërkojini kontaktit tuaj ta përmirësojë me versionin më të ri dhe mandej riprovoni.</string> <string name="qr_code_too_old_1">Kodi QR që keni skanuar vjen prej një versioni të vjetër të Briar-it.\n\nJu lutemi, kërkojini kontaktit tuaj ta përmirësojë me versionin më të ri dhe mandej riprovoni.</string>
<string name="qr_code_too_new_1">Kodi QR që keni skanuar vjen prej një versioni më të ri të Briar-it.\n\nJu lutemi, përmirësojeni me versionin më të ri dhe mandej riprovoni.</string> <string name="qr_code_too_new_1">Kodi QR që keni skanuar vjen prej një versioni më të ri të Briar-it.\n\nJu lutemi, përmirësojeni me versionin më të ri dhe mandej riprovoni.</string>
@@ -489,9 +488,8 @@ dhe smund të hapet me këtë version.\n\nJu lutemi, përmirësojeni me versi
<string name="blogs_rss_feeds_import">Importoni Prurje RSS</string> <string name="blogs_rss_feeds_import">Importoni Prurje RSS</string>
<string name="blogs_rss_feeds_import_button">Importo</string> <string name="blogs_rss_feeds_import_button">Importo</string>
<string name="blogs_rss_feeds_import_hint">Jepni URL-në e prurjes RSS</string> <string name="blogs_rss_feeds_import_hint">Jepni URL-në e prurjes RSS</string>
<string name="blogs_rss_feeds_import_progress">Po importohet Prurje RSS…</string>
<string name="blogs_rss_feeds_import_error">Na ndjeni! Pati një gabim me importimin e prurjes tuaj.</string> <string name="blogs_rss_feeds_import_error">Na ndjeni! Pati një gabim me importimin e prurjes tuaj.</string>
<string name="blogs_rss_feeds_import_title">Importo prurje nga kartelë</string> <string name="blogs_rss_feeds_import_exists">Ajo prurje është importuar tashmë.</string>
<string name="blogs_rss_feeds">Prurje RSS</string> <string name="blogs_rss_feeds">Prurje RSS</string>
<string name="blogs_rss_feeds_manage_imported">Të importuara:</string> <string name="blogs_rss_feeds_manage_imported">Të importuara:</string>
<string name="blogs_rss_feeds_manage_author">Autor:</string> <string name="blogs_rss_feeds_manage_author">Autor:</string>

View File

@@ -478,6 +478,7 @@ Vänlige installera Briar på en nyare enhet.</string>
<string name="blogs_rss_feeds_import_button">Importera</string> <string name="blogs_rss_feeds_import_button">Importera</string>
<string name="blogs_rss_feeds_import_hint">Skriv URL till RSS-flödet</string> <string name="blogs_rss_feeds_import_hint">Skriv URL till RSS-flödet</string>
<string name="blogs_rss_feeds_import_error">Tyvärr! Något gick fel när flödet skulle importeras.</string> <string name="blogs_rss_feeds_import_error">Tyvärr! Något gick fel när flödet skulle importeras.</string>
<string name="blogs_rss_feeds_import_exists">Det flödet importeras redan.</string>
<string name="blogs_rss_feeds">RSS-flöden</string> <string name="blogs_rss_feeds">RSS-flöden</string>
<string name="blogs_rss_feeds_manage_imported">Importerade:</string> <string name="blogs_rss_feeds_manage_imported">Importerade:</string>
<string name="blogs_rss_feeds_manage_author">Författare:</string> <string name="blogs_rss_feeds_manage_author">Författare:</string>

View File

@@ -482,6 +482,7 @@
<string name="blogs_rss_feeds_import_button">İçe Aktar</string> <string name="blogs_rss_feeds_import_button">İçe Aktar</string>
<string name="blogs_rss_feeds_import_hint">RSS beslemesi URL\'sini girin</string> <string name="blogs_rss_feeds_import_hint">RSS beslemesi URL\'sini girin</string>
<string name="blogs_rss_feeds_import_error">Üzgünüz! RSS beslemeniz içe aktarılırken bir hata oluştu.</string> <string name="blogs_rss_feeds_import_error">Üzgünüz! RSS beslemeniz içe aktarılırken bir hata oluştu.</string>
<string name="blogs_rss_feeds_import_exists">Bu besleme zaten içe aktarılmış.</string>
<string name="blogs_rss_feeds">RSS beslemeleri</string> <string name="blogs_rss_feeds">RSS beslemeleri</string>
<string name="blogs_rss_feeds_manage_imported">İçe Aktarıldı:</string> <string name="blogs_rss_feeds_manage_imported">İçe Aktarıldı:</string>
<string name="blogs_rss_feeds_manage_author">Yazar:</string> <string name="blogs_rss_feeds_manage_author">Yazar:</string>
@@ -593,7 +594,9 @@
<string name="mailbox_setup_download_link">İndirme Bağlantısını Paylaş</string> <string name="mailbox_setup_download_link">İndirme Bağlantısını Paylaş</string>
<string name="mailbox_setup_button_scan">Mailbox Karekodunu Tara</string> <string name="mailbox_setup_button_scan">Mailbox Karekodunu Tara</string>
<string name="permission_camera_qr_denied_body">Kameraya erişimi engellediniz, ancak Mailbox karekodunu taramak için kamerayı kullanmanız gerekiyor.\n\nLütfen erişim izni vermeyi düşünün.</string> <string name="permission_camera_qr_denied_body">Kameraya erişimi engellediniz, ancak Mailbox karekodunu taramak için kamerayı kullanmanız gerekiyor.\n\nLütfen erişim izni vermeyi düşünün.</string>
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".--> <string name="mailbox_setup_connecting">Bağlantı kuruluyor…</string>
<string name="mailbox_setup_qr_code_wrong_title">Yanlış Karekod</string>
<string name="mailbox_setup_qr_code_wrong_description">Taranan kod geçersiz. Lütfen Briar Mailbox uygulamasını Mailbox aygıtınızda açın ve gösterdiği Karekodu tarayın.</string>
<string name="mailbox_setup_already_paired_title">Mailbox zaten bağlanmış</string> <string name="mailbox_setup_already_paired_title">Mailbox zaten bağlanmış</string>
<string name="mailbox_setup_already_paired_description">Diğer aygıttan Mailbox bağlantısını kaldırın ve tekrar deneyin</string> <string name="mailbox_setup_already_paired_description">Diğer aygıttan Mailbox bağlantısını kaldırın ve tekrar deneyin</string>
<string name="mailbox_setup_io_error_title">Bağlantı kurulamıyor</string> <string name="mailbox_setup_io_error_title">Bağlantı kurulamıyor</string>

View File

@@ -20,7 +20,7 @@
<string name="dnkm_huawei_protected_text">Будь ласка, натисніть кнопку, що знаходиться нижче і впевніться у тому, що Briar захищено на екрані \"Захищені додатки\".</string> <string name="dnkm_huawei_protected_text">Будь ласка, натисніть кнопку, що знаходиться нижче і впевніться у тому, що Briar захищено на екрані \"Захищені додатки\".</string>
<string name="dnkm_huawei_protected_button">Захистити Briar</string> <string name="dnkm_huawei_protected_button">Захистити Briar</string>
<string name="dnkm_huawei_protected_help">Якщо Briar немає у списку захищених додатків, він не зможе працювати у фоновому режимі.</string> <string name="dnkm_huawei_protected_help">Якщо Briar немає у списку захищених додатків, він не зможе працювати у фоновому режимі.</string>
<string name="dnkm_huawei_app_launch_text">Будь ласка, торкніться кнопки внизу, відкрийте екран «Запуск програми» й переконайтесь, що Briar має налаштування «Керувати вручну».</string> <string name="dnkm_huawei_app_launch_text">Будь ласка, торкніть кнопку внизу, відкрийте екран «Запуск програми» й переконайтесь, що Briar має налаштування «Керувати вручну».</string>
<string name="dnkm_huawei_app_launch_help">Якщо не вказати «Керувати вручну» для Briar на екрані «Запуск програми», він не зможе працювати в фоновому режимі.</string> <string name="dnkm_huawei_app_launch_help">Якщо не вказати «Керувати вручну» для Briar на екрані «Запуск програми», він не зможе працювати в фоновому режимі.</string>
<string name="dnkm_xiaomi_text">Щоб Briar працював у фоновому режимі, закріпіть його в переліку недавніх застосунків.</string> <string name="dnkm_xiaomi_text">Щоб Briar працював у фоновому режимі, закріпіть його в переліку недавніх застосунків.</string>
<string name="dnkm_xiaomi_button">Захистити Briar</string> <string name="dnkm_xiaomi_button">Захистити Briar</string>
@@ -505,6 +505,7 @@
<string name="blogs_rss_feeds_import_button">Імпортувати</string> <string name="blogs_rss_feeds_import_button">Імпортувати</string>
<string name="blogs_rss_feeds_import_hint">Введіть URL-посилання RSS-стрічки</string> <string name="blogs_rss_feeds_import_hint">Введіть URL-посилання RSS-стрічки</string>
<string name="blogs_rss_feeds_import_error">Нам шкода! Виникла помилка під час імпорту вашої стрічки.</string> <string name="blogs_rss_feeds_import_error">Нам шкода! Виникла помилка під час імпорту вашої стрічки.</string>
<string name="blogs_rss_feeds_import_exists">Цю стрічку вже імпортовано.</string>
<string name="blogs_rss_feeds">RSS-стрічки</string> <string name="blogs_rss_feeds">RSS-стрічки</string>
<string name="blogs_rss_feeds_manage_imported">Імпортовано:</string> <string name="blogs_rss_feeds_manage_imported">Імпортовано:</string>
<string name="blogs_rss_feeds_manage_author">Автор:</string> <string name="blogs_rss_feeds_manage_author">Автор:</string>
@@ -515,7 +516,7 @@
<string name="blogs_rss_feeds_manage_empty_state">Немає RSS-стрічок до відображення\n\nНатисніть на символ \"+\", щоб імпортувати стрічку</string> <string name="blogs_rss_feeds_manage_empty_state">Немає RSS-стрічок до відображення\n\nНатисніть на символ \"+\", щоб імпортувати стрічку</string>
<string name="blogs_rss_feeds_manage_error">Під час завантаження ваших стрічок виникла проблема. Будь ласка, спробуйте пізніше.</string> <string name="blogs_rss_feeds_manage_error">Під час завантаження ваших стрічок виникла проблема. Будь ласка, спробуйте пізніше.</string>
<!--Settings Profile Picture--> <!--Settings Profile Picture-->
<string name="change_profile_picture">Торкніться, щоб змінити зображення профілю</string> <string name="change_profile_picture">Торкніть, щоб змінити зображення профілю</string>
<string name="dialog_confirm_profile_picture_title">Змінити зображення профілю</string> <string name="dialog_confirm_profile_picture_title">Змінити зображення профілю</string>
<string name="dialog_confirm_profile_picture_remark">Лише ваші контакти можуть бачити це зображення</string> <string name="dialog_confirm_profile_picture_remark">Лише ваші контакти можуть бачити це зображення</string>
<string name="change_profile_picture_failed_message">Перепрошуємо, щось пішло не так при оновленні вашого зображення профілю</string> <string name="change_profile_picture_failed_message">Перепрошуємо, щось пішло не так при оновленні вашого зображення профілю</string>
@@ -826,12 +827,12 @@
<string name="removable_drive_explanation">Якщо не вдається з\'єднатися з контактом через інтернет, Wi-Fi та Bluetooth, Briar ще може передавати повідомлення за допомогою флешки чи SD-картки.\n\nКоли ви натиснете кнопку «Надіслати дані», будь-які дані в очікуванні надсилання контактові буде записано на флешку. Зокрема дані особистих повідомлень, прикріплень, блогів, форумів і приватних груп.\n\nПеред записом на флешку все буде зашифровано.\n\nОтримавши флешку, ваш контакт зможе імпортувати повідомлення в свій Briar кнопкою «Отримати дані».</string> <string name="removable_drive_explanation">Якщо не вдається з\'єднатися з контактом через інтернет, Wi-Fi та Bluetooth, Briar ще може передавати повідомлення за допомогою флешки чи SD-картки.\n\nКоли ви натиснете кнопку «Надіслати дані», будь-які дані в очікуванні надсилання контактові буде записано на флешку. Зокрема дані особистих повідомлень, прикріплень, блогів, форумів і приватних груп.\n\nПеред записом на флешку все буде зашифровано.\n\nОтримавши флешку, ваш контакт зможе імпортувати повідомлення в свій Briar кнопкою «Отримати дані».</string>
<string name="removable_drive_title_send">Надіслати дані</string> <string name="removable_drive_title_send">Надіслати дані</string>
<string name="removable_drive_title_receive">Отримати дані</string> <string name="removable_drive_title_receive">Отримати дані</string>
<string name="removable_drive_send_intro">Торкніться кнопки внизу, щоб створити файл із зашифрованими повідомленнями. Ви зможете обрати, куди зберегти файл.\n\nЯкщо бажаєте зберегти файл на флешку, під\'єднайте її зараз.</string> <string name="removable_drive_send_intro">Торкніть кнопку внизу, щоб створити файл зашифрованих повідомлень. Ви зможете обрати, куди зберегти файл.\n\nЯкщо бажаєте зберегти файл на флешку, під\'єднайте її зараз.</string>
<string name="removable_drive_send_no_data">Жодне повідомлення не очікує на надсилання цьому контактові.</string> <string name="removable_drive_send_no_data">Жодне повідомлення не очікує на надсилання цьому контактові.</string>
<string name="removable_drive_send_not_supported">Контакт використовує стару версію Briar чи старий пристрій, що не підтримує цієї можливості.</string> <string name="removable_drive_send_not_supported">Контакт використовує стару версію Briar чи старий пристрій, що не підтримує цієї можливості.</string>
<string name="removable_drive_send_button">Оберіть файл експорту</string> <string name="removable_drive_send_button">Оберіть файл експорту</string>
<string name="removable_drive_ongoing">Дочекайтесь завершення поточного завдання</string> <string name="removable_drive_ongoing">Дочекайтесь завершення поточного завдання</string>
<string name="removable_drive_receive_intro">Торкніться кнопки внизу, щоб обрати файл, надісланий вам контактом.\n\nЯкщо файл на флешці, під\'єднайте її зараз.</string> <string name="removable_drive_receive_intro">Торкніть кнопку внизу, щоб обрати файл, надісланий вам контактом.\n\nЯкщо файл на флешці, під\'єднайте її зараз.</string>
<string name="removable_drive_receive_button">Оберіть файл імпорту</string> <string name="removable_drive_receive_button">Оберіть файл імпорту</string>
<string name="removable_drive_success_send_title">Експорт успішний</string> <string name="removable_drive_success_send_title">Експорт успішний</string>
<string name="removable_drive_success_send_text">Дані успішно експортовано. Маєте 28 днів, щоб передати файл контактові.\n\nЯкщо файл на флешці, перед від\'єднанням вимкніть її за допомогою сповіщення в рядку стану.</string> <string name="removable_drive_success_send_text">Дані успішно експортовано. Маєте 28 днів, щоб передати файл контактові.\n\nЯкщо файл на флешці, перед від\'єднанням вимкніть її за допомогою сповіщення в рядку стану.</string>

View File

@@ -225,7 +225,6 @@
<string name="exchanging_contact_details">正在交换联系人详细信息\u2026</string> <string name="exchanging_contact_details">正在交换联系人详细信息\u2026</string>
<string name="contact_added_toast">联系人已添加:%s</string> <string name="contact_added_toast">联系人已添加:%s</string>
<string name="contact_already_exists">联系人 %s 已存在</string> <string name="contact_already_exists">联系人 %s 已存在</string>
<string name="contact_already_exists_general">联系人已存在</string>
<string name="qr_code_invalid">二维码无效</string> <string name="qr_code_invalid">二维码无效</string>
<string name="qr_code_too_old_1">您扫描的二维码来自旧版本的 Briar。\n\n请让您的联系人升级到最新版本然后重试。</string> <string name="qr_code_too_old_1">您扫描的二维码来自旧版本的 Briar。\n\n请让您的联系人升级到最新版本然后重试。</string>
<string name="qr_code_too_new_1">您扫描的二维码来自新版本的 Briar。\n\n请升级到最新版本然后重试。</string> <string name="qr_code_too_new_1">您扫描的二维码来自新版本的 Briar。\n\n请升级到最新版本然后重试。</string>
@@ -474,9 +473,8 @@
<string name="blogs_rss_feeds_import">导入 RSS 订阅源</string> <string name="blogs_rss_feeds_import">导入 RSS 订阅源</string>
<string name="blogs_rss_feeds_import_button">导入</string> <string name="blogs_rss_feeds_import_button">导入</string>
<string name="blogs_rss_feeds_import_hint">输入 RSS 订阅源链接</string> <string name="blogs_rss_feeds_import_hint">输入 RSS 订阅源链接</string>
<string name="blogs_rss_feeds_import_progress">导入 RSS 订阅源中…</string>
<string name="blogs_rss_feeds_import_error">抱歉!导入订阅源时发生错误。</string> <string name="blogs_rss_feeds_import_error">抱歉!导入订阅源时发生错误。</string>
<string name="blogs_rss_feeds_import_title">从文件导入</string> <string name="blogs_rss_feeds_import_exists">已经导入那个</string>
<string name="blogs_rss_feeds">RSS源 </string> <string name="blogs_rss_feeds">RSS源 </string>
<string name="blogs_rss_feeds_manage_imported">已导入:</string> <string name="blogs_rss_feeds_manage_imported">已导入:</string>
<string name="blogs_rss_feeds_manage_author">作者:</string> <string name="blogs_rss_feeds_manage_author">作者:</string>

Some files were not shown because too many files have changed in this diff Show More