Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d280e7b64 | ||
|
|
e6918a5857 | ||
|
|
dca8245ba4 | ||
|
|
9550817078 | ||
|
|
7a91860735 | ||
|
|
0f4abac8c2 | ||
|
|
b16050b978 | ||
|
|
aced62fec3 | ||
|
|
5155e24bc7 | ||
|
|
3aabe3a51d | ||
|
|
17de015b90 | ||
|
|
f19e71b333 | ||
|
|
8fea354b74 | ||
|
|
7a81c27cc6 | ||
|
|
ea5808d833 | ||
|
|
8b045a826a | ||
|
|
1a6e078510 | ||
|
|
daff8010cd | ||
|
|
4035930e0e | ||
|
|
fc63a384b2 | ||
|
|
2f3449b651 | ||
|
|
31c65a39e4 | ||
|
|
7ba20928c3 | ||
|
|
c482cbbe70 | ||
|
|
4042a3e406 | ||
|
|
392132dc3b | ||
|
|
459a3dc58c | ||
|
|
194a8b0922 | ||
|
|
8a8336ae08 | ||
|
|
458e0b3b8b | ||
|
|
9758dc6422 | ||
|
|
e4a9fb8a27 | ||
|
|
f0473fde17 | ||
|
|
e2980a5210 | ||
|
|
764da14440 | ||
|
|
7da6c627fe | ||
|
|
0a092b5b7f | ||
|
|
9f8af2327d | ||
|
|
345e24142e | ||
|
|
0fdd03ddee | ||
|
|
a0fa288cb6 | ||
|
|
70bac24832 | ||
|
|
1df40fbdeb | ||
|
|
91e9ffff85 | ||
|
|
853df14e2f | ||
|
|
e17a772bb6 | ||
|
|
90e027d9a4 | ||
|
|
fdc9a5d8b0 | ||
|
|
543891a0a0 | ||
|
|
06921443fc |
@@ -57,6 +57,7 @@ Marc Pujol <kilburn@la3.org>
|
|||||||
Marcin Dziadus <dziadus.marcin@gmail.com>
|
Marcin Dziadus <dziadus.marcin@gmail.com>
|
||||||
Mateusz Naściszewski <matin1111@wp.pl>
|
Mateusz Naściszewski <matin1111@wp.pl>
|
||||||
Matt Burke <mburke@amplify.com> <burkemw3@gmail.com>
|
Matt Burke <mburke@amplify.com> <burkemw3@gmail.com>
|
||||||
|
Max Schulze <max.schulze@online.de> <kralo@users.noreply.github.com>
|
||||||
Michael Jephcote <rewt0r@gmx.com> <Rewt0r@users.noreply.github.com>
|
Michael Jephcote <rewt0r@gmx.com> <Rewt0r@users.noreply.github.com>
|
||||||
Michael Ploujnikov <ploujj@gmail.com>
|
Michael Ploujnikov <ploujj@gmail.com>
|
||||||
Michael Tilli <pyfisch@gmail.com>
|
Michael Tilli <pyfisch@gmail.com>
|
||||||
@@ -80,4 +81,5 @@ Veeti Paananen <veeti.paananen@rojekti.fi>
|
|||||||
Victor Buinsky <vix_booja@tut.by>
|
Victor Buinsky <vix_booja@tut.by>
|
||||||
Vil Brekin <vilbrekin@gmail.com>
|
Vil Brekin <vilbrekin@gmail.com>
|
||||||
William A. Kennington III <william@wkennington.com>
|
William A. Kennington III <william@wkennington.com>
|
||||||
|
Wulf Weich <wweich@users.noreply.github.com> <wweich@gmx.de>
|
||||||
Yannic A. <eipiminusone+github@gmail.com> <eipiminus1@users.noreply.github.com>
|
Yannic A. <eipiminusone+github@gmail.com> <eipiminus1@users.noreply.github.com>
|
||||||
|
|||||||
Generated
+1
-4
@@ -11,18 +11,15 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/calmh/du",
|
"ImportPath": "github.com/calmh/du",
|
||||||
"Comment": "v1.0.0",
|
|
||||||
"Rev": "3c0690cca16228b97741327b1b6781397afbdb24"
|
"Rev": "3c0690cca16228b97741327b1b6781397afbdb24"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/calmh/luhn",
|
"ImportPath": "github.com/calmh/luhn",
|
||||||
"Comment": "v1.0.0",
|
|
||||||
"Rev": "0c8388ff95fa92d4094011e5a04fc99dea3d1632"
|
"Rev": "0c8388ff95fa92d4094011e5a04fc99dea3d1632"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/calmh/xdr",
|
"ImportPath": "github.com/calmh/xdr",
|
||||||
"Comment": "v2.0.0",
|
"Rev": "9eb3e1a622d9364deb39c831f7e5f164393d7e37"
|
||||||
"Rev": "b6e0c321c9b5b28ba5ee21e828323e4b982c6976"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/golang/snappy",
|
"ImportPath": "github.com/golang/snappy",
|
||||||
|
|||||||
+4
-2
@@ -6,5 +6,7 @@ xdr
|
|||||||
[](http://godoc.org/github.com/calmh/xdr)
|
[](http://godoc.org/github.com/calmh/xdr)
|
||||||
[](http://opensource.org/licenses/MIT)
|
[](http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
This is an XDR marshalling/unmarshalling library. It uses code generation and
|
This is an XDR encoding/decoding library. It uses code generation and
|
||||||
not reflection.
|
not reflection. It supports the IPDR bastardized XDR format when built
|
||||||
|
with `-tags ipdr`.
|
||||||
|
|
||||||
|
|||||||
+159
-215
@@ -36,73 +36,31 @@ type structInfo struct {
|
|||||||
Fields []fieldInfo
|
Fields []fieldInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i structInfo) SizeExpr() string {
|
var headerTpl = template.Must(template.New("header").Parse(`// ************************************************************
|
||||||
var xdrSizes = map[string]int{
|
|
||||||
"int8": 4,
|
|
||||||
"uint8": 4,
|
|
||||||
"int16": 4,
|
|
||||||
"uint16": 4,
|
|
||||||
"int32": 4,
|
|
||||||
"uint32": 4,
|
|
||||||
"int64": 8,
|
|
||||||
"uint64": 8,
|
|
||||||
"int": 8,
|
|
||||||
"bool": 4,
|
|
||||||
}
|
|
||||||
|
|
||||||
var terms []string
|
|
||||||
nl := ""
|
|
||||||
for _, f := range i.Fields {
|
|
||||||
if size := xdrSizes[f.FieldType]; size > 0 {
|
|
||||||
if f.IsSlice {
|
|
||||||
terms = append(terms, nl+"4+len(o."+f.Name+")*"+strconv.Itoa(size))
|
|
||||||
} else {
|
|
||||||
terms = append(terms, strconv.Itoa(size))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch f.FieldType {
|
|
||||||
case "string", "[]byte":
|
|
||||||
if f.IsSlice {
|
|
||||||
terms = append(terms, nl+"4+xdr.SizeOfSlice(o."+f.Name+")")
|
|
||||||
} else {
|
|
||||||
terms = append(terms, nl+"4+len(o."+f.Name+")+xdr.Padding(len(o."+f.Name+"))")
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if f.IsSlice {
|
|
||||||
terms = append(terms, nl+"4+xdr.SizeOfSlice(o."+f.Name+")")
|
|
||||||
} else {
|
|
||||||
terms = append(terms, nl+"o."+f.Name+".XDRSize()")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nl = "\n"
|
|
||||||
}
|
|
||||||
return strings.Join(terms, "+")
|
|
||||||
}
|
|
||||||
|
|
||||||
var headerData = `// ************************************************************
|
|
||||||
// This file is automatically generated by genxdr. Do not edit.
|
// This file is automatically generated by genxdr. Do not edit.
|
||||||
// ************************************************************
|
// ************************************************************
|
||||||
|
|
||||||
package {{.Package}}
|
package {{.Package}}
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
|
||||||
"github.com/calmh/xdr"
|
"github.com/calmh/xdr"
|
||||||
)
|
)
|
||||||
`
|
`))
|
||||||
|
|
||||||
var encoderData = `
|
var encodeTpl = template.Must(template.New("encoder").Parse(`
|
||||||
func (o {{.Name}}) XDRSize() int {
|
func (o {{.TypeName}}) EncodeXDR(w io.Writer) (int, error) {
|
||||||
return {{.SizeExpr}}
|
var xw = xdr.NewWriter(w)
|
||||||
|
return o.EncodeXDRInto(xw)
|
||||||
}//+n
|
}//+n
|
||||||
|
|
||||||
func (o {{.Name}}) MarshalXDR() ([]byte, error) {
|
func (o {{.TypeName}}) MarshalXDR() ([]byte, error) {
|
||||||
buf:= make([]byte, o.XDRSize())
|
return o.AppendXDR(make([]byte, 0, 128))
|
||||||
m := &xdr.Marshaller{Data: buf}
|
|
||||||
return buf, o.MarshalXDRInto(m)
|
|
||||||
}//+n
|
}//+n
|
||||||
|
|
||||||
func (o {{.Name}}) MustMarshalXDR() []byte {
|
func (o {{.TypeName}}) MustMarshalXDR() []byte {
|
||||||
bs, err := o.MarshalXDR()
|
bs, err := o.MarshalXDR()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -110,155 +68,141 @@ func (o {{.Name}}) MustMarshalXDR() []byte {
|
|||||||
return bs
|
return bs
|
||||||
}//+n
|
}//+n
|
||||||
|
|
||||||
func (o {{.Name}}) MarshalXDRInto(m *xdr.Marshaller) error {
|
func (o {{.TypeName}}) AppendXDR(bs []byte) ([]byte, error) {
|
||||||
{{range $fi := .Fields}}
|
var aw = xdr.AppendWriter(bs)
|
||||||
{{if $fi.IsSlice}}
|
var xw = xdr.NewWriter(&aw)
|
||||||
{{template "marshalSlice" $fi}}
|
_, err := o.EncodeXDRInto(xw)
|
||||||
{{else}}
|
return []byte(aw), err
|
||||||
{{template "marshalValue" $fi}}
|
|
||||||
{{end}}
|
|
||||||
{{end}}
|
|
||||||
return m.Error
|
|
||||||
}//+n
|
}//+n
|
||||||
|
|
||||||
{{define "marshalValue"}}
|
func (o {{.TypeName}}) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
{{if ne .Convert ""}}
|
{{range $fieldInfo := .Fields}}
|
||||||
m.Marshal{{.Encoder}}({{.Convert}}(o.{{.Name}}))
|
{{if not $fieldInfo.IsSlice}}
|
||||||
{{else if .IsBasic}}
|
{{if ne $fieldInfo.Convert ""}}
|
||||||
{{if ge .Max 1}}
|
xw.Write{{$fieldInfo.Encoder}}({{$fieldInfo.Convert}}(o.{{$fieldInfo.Name}}))
|
||||||
if l := len(o.{{.Name}}); l > {{.Max}} {
|
{{else if $fieldInfo.IsBasic}}
|
||||||
return xdr.ElementSizeExceeded("{{.Name}}", l, {{.Max}})
|
{{if ge $fieldInfo.Max 1}}
|
||||||
|
if l := len(o.{{$fieldInfo.Name}}); l > {{$fieldInfo.Max}} {
|
||||||
|
return xw.Tot(), xdr.ElementSizeExceeded("{{$fieldInfo.Name}}", l, {{$fieldInfo.Max}})
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
|
xw.Write{{$fieldInfo.Encoder}}(o.{{$fieldInfo.Name}})
|
||||||
|
{{else}}
|
||||||
|
_, err := o.{{$fieldInfo.Name}}.EncodeXDRInto(xw)
|
||||||
|
if err != nil {
|
||||||
|
return xw.Tot(), err
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
|
{{else}}
|
||||||
|
{{if ge $fieldInfo.Max 1}}
|
||||||
|
if l := len(o.{{$fieldInfo.Name}}); l > {{$fieldInfo.Max}} {
|
||||||
|
return xw.Tot(), xdr.ElementSizeExceeded("{{$fieldInfo.Name}}", l, {{$fieldInfo.Max}})
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
|
xw.WriteUint32(uint32(len(o.{{$fieldInfo.Name}})))
|
||||||
|
for i := range o.{{$fieldInfo.Name}} {
|
||||||
|
{{if ne $fieldInfo.Convert ""}}
|
||||||
|
xw.Write{{$fieldInfo.Encoder}}({{$fieldInfo.Convert}}(o.{{$fieldInfo.Name}}[i]))
|
||||||
|
{{else if $fieldInfo.IsBasic}}
|
||||||
|
xw.Write{{$fieldInfo.Encoder}}(o.{{$fieldInfo.Name}}[i])
|
||||||
|
{{else}}
|
||||||
|
_, err := o.{{$fieldInfo.Name}}[i].EncodeXDRInto(xw)
|
||||||
|
if err != nil {
|
||||||
|
return xw.Tot(), err
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
}
|
}
|
||||||
{{end}}
|
{{end}}
|
||||||
m.Marshal{{.Encoder}}(o.{{.Name}})
|
|
||||||
{{else}}
|
|
||||||
if err := o.{{.Name}}.MarshalXDRInto(m); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
return xw.Tot(), xw.Error()
|
||||||
|
|
||||||
{{define "marshalSlice"}}
|
|
||||||
{{if ge .Max 1}}
|
|
||||||
if l := len(o.{{.Name}}); l > {{.Max}} {
|
|
||||||
return xdr.ElementSizeExceeded("{{.Name}}", l, {{.Max}})
|
|
||||||
}
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
m.MarshalUint32(uint32(len(o.{{.Name}})))
|
|
||||||
for i := range o.{{.Name}} {
|
|
||||||
{{if ne .Convert ""}}
|
|
||||||
m.Marshal{{.Encoder}}({{.Convert}}(o.{{.Name}}[i]))
|
|
||||||
{{else if .IsBasic}}
|
|
||||||
m.Marshal{{.Encoder}}(o.{{.Name}}[i])
|
|
||||||
{{else}}
|
|
||||||
if err := o.{{.Name}}[i].MarshalXDRInto(m); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
{{end}}
|
|
||||||
}
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
func (o *{{.Name}}) UnmarshalXDR(bs []byte) error {
|
|
||||||
u := &xdr.Unmarshaller{Data: bs}
|
|
||||||
return o.UnmarshalXDRFrom(u)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *{{.Name}}) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
|
|
||||||
{{range $fi := .Fields}}
|
|
||||||
{{if $fi.IsSlice}}
|
|
||||||
{{template "unmarshalSlice" $fi}}
|
|
||||||
{{else}}
|
|
||||||
{{template "unmarshalValue" $fi}}
|
|
||||||
{{end}}
|
|
||||||
{{end}}
|
|
||||||
return u.Error
|
|
||||||
}//+n
|
}//+n
|
||||||
|
|
||||||
{{define "unmarshalValue"}}
|
func (o *{{.TypeName}}) DecodeXDR(r io.Reader) error {
|
||||||
{{if ne .Convert ""}}
|
xr := xdr.NewReader(r)
|
||||||
o.{{.Name}} = {{.FieldType}}(u.Unmarshal{{.Encoder}}())
|
return o.DecodeXDRFrom(xr)
|
||||||
{{else if .IsBasic}}
|
}//+n
|
||||||
{{if ge .Max 1}}
|
|
||||||
o.{{.Name}} = u.Unmarshal{{.Encoder}}Max({{.Max}})
|
|
||||||
{{else}}
|
|
||||||
o.{{.Name}} = u.Unmarshal{{.Encoder}}()
|
|
||||||
{{end}}
|
|
||||||
{{else}}
|
|
||||||
(&o.{{.Name}}).UnmarshalXDRFrom(u)
|
|
||||||
{{end}}
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{define "unmarshalSlice"}}
|
func (o *{{.TypeName}}) UnmarshalXDR(bs []byte) error {
|
||||||
_{{.Name}}Size := int(u.UnmarshalUint32())
|
var br = bytes.NewReader(bs)
|
||||||
if _{{.Name}}Size < 0 {
|
var xr = xdr.NewReader(br)
|
||||||
return xdr.ElementSizeExceeded("{{.Name}}", _{{.Name}}Size, {{.Max}})
|
return o.DecodeXDRFrom(xr)
|
||||||
} else if _{{.Name}}Size == 0 {
|
}//+n
|
||||||
o.{{.Name}} = nil
|
|
||||||
} else {
|
func (o *{{.TypeName}}) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
{{if ge .Max 1}}
|
{{range $fieldInfo := .Fields}}
|
||||||
if _{{.Name}}Size > {{.Max}} {
|
{{if not $fieldInfo.IsSlice}}
|
||||||
return xdr.ElementSizeExceeded("{{.Name}}", _{{.Name}}Size, {{.Max}})
|
{{if ne $fieldInfo.Convert ""}}
|
||||||
}
|
o.{{$fieldInfo.Name}} = {{$fieldInfo.FieldType}}(xr.Read{{$fieldInfo.Encoder}}())
|
||||||
{{end}}
|
{{else if $fieldInfo.IsBasic}}
|
||||||
if _{{.Name}}Size <= len(o.{{.Name}}) {
|
{{if ge $fieldInfo.Max 1}}
|
||||||
{{if eq .FieldType "string"}}
|
o.{{$fieldInfo.Name}} = xr.Read{{$fieldInfo.Encoder}}Max({{$fieldInfo.Max}})
|
||||||
for i := _{{.Name}}Size; i < len(o.{{.Name}}); i++ { o.{{.Name}}[i] = "" }
|
|
||||||
{{end}}
|
|
||||||
{{if eq .FieldType "[]byte"}}
|
|
||||||
for i := _{{.Name}}Size; i < len(o.{{.Name}}); i++ { o.{{.Name}}[i] = nil }
|
|
||||||
{{end}}
|
|
||||||
o.{{.Name}} = o.{{.Name}}[:_{{.Name}}Size]
|
|
||||||
} else {
|
|
||||||
o.{{.Name}} = make([]{{.FieldType}}, _{{.Name}}Size)
|
|
||||||
}
|
|
||||||
for i := range o.{{.Name}} {
|
|
||||||
{{if ne .Convert ""}}
|
|
||||||
o.{{.Name}}[i] = {{.FieldType}}(u.Unmarshal{{.Encoder}}())
|
|
||||||
{{else if .IsBasic}}
|
|
||||||
{{if ge .Submax 1}}
|
|
||||||
o.{{.Name}}[i] = u.Unmarshal{{.Encoder}}Max({{.Submax}})
|
|
||||||
{{else}}
|
{{else}}
|
||||||
o.{{.Name}}[i] = u.Unmarshal{{.Encoder}}()
|
o.{{$fieldInfo.Name}} = xr.Read{{$fieldInfo.Encoder}}()
|
||||||
{{end}}
|
{{end}}
|
||||||
{{else}}
|
{{else}}
|
||||||
(&o.{{.Name}}[i]).UnmarshalXDRFrom(u)
|
(&o.{{$fieldInfo.Name}}).DecodeXDRFrom(xr)
|
||||||
{{end}}
|
{{end}}
|
||||||
}
|
{{else}}
|
||||||
}
|
_{{$fieldInfo.Name}}Size := int(xr.ReadUint32())
|
||||||
{{end}}
|
if _{{$fieldInfo.Name}}Size < 0 {
|
||||||
`
|
return xdr.ElementSizeExceeded("{{$fieldInfo.Name}}", _{{$fieldInfo.Name}}Size, {{$fieldInfo.Max}})
|
||||||
|
}
|
||||||
var (
|
{{if ge $fieldInfo.Max 1}}
|
||||||
encodeTpl = template.Must(template.New("encoder").Parse(encoderData))
|
if _{{$fieldInfo.Name}}Size > {{$fieldInfo.Max}} {
|
||||||
headerTpl = template.Must(template.New("header").Parse(headerData))
|
return xdr.ElementSizeExceeded("{{$fieldInfo.Name}}", _{{$fieldInfo.Name}}Size, {{$fieldInfo.Max}})
|
||||||
)
|
}
|
||||||
|
{{end}}
|
||||||
|
o.{{$fieldInfo.Name}} = make([]{{$fieldInfo.FieldType}}, _{{$fieldInfo.Name}}Size)
|
||||||
|
for i := range o.{{$fieldInfo.Name}} {
|
||||||
|
{{if ne $fieldInfo.Convert ""}}
|
||||||
|
o.{{$fieldInfo.Name}}[i] = {{$fieldInfo.FieldType}}(xr.Read{{$fieldInfo.Encoder}}())
|
||||||
|
{{else if $fieldInfo.IsBasic}}
|
||||||
|
{{if ge $fieldInfo.Submax 1}}
|
||||||
|
o.{{$fieldInfo.Name}}[i] = xr.Read{{$fieldInfo.Encoder}}Max({{$fieldInfo.Submax}})
|
||||||
|
{{else}}
|
||||||
|
o.{{$fieldInfo.Name}}[i] = xr.Read{{$fieldInfo.Encoder}}()
|
||||||
|
{{end}}
|
||||||
|
{{else}}
|
||||||
|
(&o.{{$fieldInfo.Name}}[i]).DecodeXDRFrom(xr)
|
||||||
|
{{end}}
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
return xr.Error()
|
||||||
|
}`))
|
||||||
|
|
||||||
var emptyTypeTpl = template.Must(template.New("encoder").Parse(`
|
var emptyTypeTpl = template.Must(template.New("encoder").Parse(`
|
||||||
func (o {{.Name}}) XDRSize() int {
|
func (o {{.TypeName}}) EncodeXDR(w io.Writer) (int, error) {
|
||||||
return 0
|
return 0, nil
|
||||||
}
|
}//+n
|
||||||
|
|
||||||
func (o {{.Name}}) MarshalXDR() ([]byte, error) {
|
func (o {{.TypeName}}) MarshalXDR() ([]byte, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}//+n
|
}//+n
|
||||||
|
|
||||||
func (o {{.Name}}) MustMarshalXDR() []byte {
|
func (o {{.TypeName}}) MustMarshalXDR() []byte {
|
||||||
return nil
|
return nil
|
||||||
}//+n
|
}//+n
|
||||||
|
|
||||||
func (o {{.Name}}) MarshalXDRInto(m *xdr.Marshaller) error {
|
func (o {{.TypeName}}) AppendXDR(bs []byte) ([]byte, error) {
|
||||||
|
return bs, nil
|
||||||
|
}//+n
|
||||||
|
|
||||||
|
func (o {{.TypeName}}) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
|
return xw.Tot(), xw.Error()
|
||||||
|
}//+n
|
||||||
|
|
||||||
|
func (o *{{.TypeName}}) DecodeXDR(r io.Reader) error {
|
||||||
return nil
|
return nil
|
||||||
}//+n
|
}//+n
|
||||||
|
|
||||||
func (o *{{.Name}}) UnmarshalXDR(bs []byte) error {
|
func (o *{{.TypeName}}) UnmarshalXDR(bs []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}//+n
|
}//+n
|
||||||
|
|
||||||
func (o *{{.Name}}) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
|
func (o *{{.TypeName}}) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
return nil
|
return xr.Error()
|
||||||
}//+n
|
}`))
|
||||||
`))
|
|
||||||
|
|
||||||
var maxRe = regexp.MustCompile(`(?:\Wmax:)(\d+)(?:\s*,\s*(\d+))?`)
|
var maxRe = regexp.MustCompile(`(?:\Wmax:)(\d+)(?:\s*,\s*(\d+))?`)
|
||||||
|
|
||||||
@@ -342,7 +286,7 @@ func handleStruct(t *ast.StructType) []fieldInfo {
|
|||||||
f = fieldInfo{
|
f = fieldInfo{
|
||||||
Name: fn,
|
Name: fn,
|
||||||
IsBasic: true,
|
IsBasic: true,
|
||||||
FieldType: "[]" + tn,
|
FieldType: tn,
|
||||||
Encoder: enc.Encoder,
|
Encoder: enc.Encoder,
|
||||||
Convert: enc.Type,
|
Convert: enc.Type,
|
||||||
Max: max1,
|
Max: max1,
|
||||||
@@ -385,14 +329,17 @@ func handleStruct(t *ast.StructType) []fieldInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func generateCode(output io.Writer, s structInfo) {
|
func generateCode(output io.Writer, s structInfo) {
|
||||||
|
name := s.Name
|
||||||
|
fs := s.Fields
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
var err error
|
var err error
|
||||||
if len(s.Fields) == 0 {
|
if len(fs) == 0 {
|
||||||
// This is an empty type. We can create a quite simple codec for it.
|
// This is an empty type. We can create a quite simple codec for it.
|
||||||
err = emptyTypeTpl.Execute(&buf, s)
|
err = emptyTypeTpl.Execute(&buf, map[string]interface{}{"TypeName": name})
|
||||||
} else {
|
} else {
|
||||||
// Generate with the default template.
|
// Generate with the default template.
|
||||||
err = encodeTpl.Execute(&buf, s)
|
err = encodeTpl.Execute(&buf, map[string]interface{}{"TypeName": name, "Fields": fs})
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -400,7 +347,12 @@ func generateCode(output io.Writer, s structInfo) {
|
|||||||
|
|
||||||
bs := regexp.MustCompile(`(\s*\n)+`).ReplaceAll(buf.Bytes(), []byte("\n"))
|
bs := regexp.MustCompile(`(\s*\n)+`).ReplaceAll(buf.Bytes(), []byte("\n"))
|
||||||
bs = bytes.Replace(bs, []byte("//+n"), []byte("\n"), -1)
|
bs = bytes.Replace(bs, []byte("//+n"), []byte("\n"), -1)
|
||||||
output.Write(bs)
|
|
||||||
|
bs, err = format.Source(bs)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Fprintln(output, string(bs))
|
||||||
}
|
}
|
||||||
|
|
||||||
func uncamelize(s string) string {
|
func uncamelize(s string) string {
|
||||||
@@ -432,46 +384,46 @@ func generateDiagram(output io.Writer, s structInfo) {
|
|||||||
tn := f.FieldType
|
tn := f.FieldType
|
||||||
name := uncamelize(f.Name)
|
name := uncamelize(f.Name)
|
||||||
|
|
||||||
suffix := ""
|
|
||||||
if f.IsSlice {
|
if f.IsSlice {
|
||||||
fmt.Fprintf(output, "| %s |\n", center("Number of "+name, 61))
|
fmt.Fprintf(output, "| %s |\n", center("Number of "+name, 61))
|
||||||
fmt.Fprintln(output, line)
|
fmt.Fprintln(output, line)
|
||||||
suffix = " (n items)"
|
|
||||||
fmt.Fprintf(output, "/ %s /\n", center("", 61))
|
|
||||||
}
|
}
|
||||||
switch tn {
|
switch tn {
|
||||||
case "bool":
|
case "bool":
|
||||||
fmt.Fprintf(output, "| %s |V|\n", center(name+" (V=0 or 1)", 59))
|
fmt.Fprintf(output, "| %s |V|\n", center(name+" (V=0 or 1)", 59))
|
||||||
|
fmt.Fprintln(output, line)
|
||||||
case "int16", "uint16":
|
case "int16", "uint16":
|
||||||
fmt.Fprintf(output, "| %s | %s |\n", center("16 zero bits", 29), center(name, 29))
|
fmt.Fprintf(output, "| %s | %s |\n", center("0x0000", 29), center(name, 29))
|
||||||
case "int8", "uint8":
|
fmt.Fprintln(output, line)
|
||||||
fmt.Fprintf(output, "| %s | %s |\n", center("24 zero bits", 45), center(name, 13))
|
|
||||||
case "int32", "uint32":
|
case "int32", "uint32":
|
||||||
fmt.Fprintf(output, "| %s |\n", center(name+suffix, 61))
|
fmt.Fprintf(output, "| %s |\n", center(name, 61))
|
||||||
|
fmt.Fprintln(output, line)
|
||||||
case "int64", "uint64":
|
case "int64", "uint64":
|
||||||
fmt.Fprintf(output, "| %-61s |\n", "")
|
fmt.Fprintf(output, "| %-61s |\n", "")
|
||||||
fmt.Fprintf(output, "+ %s +\n", center(name+" (64 bits)", 61))
|
fmt.Fprintf(output, "+ %s +\n", center(name+" (64 bits)", 61))
|
||||||
fmt.Fprintf(output, "| %-61s |\n", "")
|
fmt.Fprintf(output, "| %-61s |\n", "")
|
||||||
case "string", "[]byte":
|
fmt.Fprintln(output, line)
|
||||||
|
case "string", "byte": // XXX We assume slice of byte!
|
||||||
|
fmt.Fprintf(output, "| %s |\n", center("Length of "+name, 61))
|
||||||
|
fmt.Fprintln(output, line)
|
||||||
fmt.Fprintf(output, "/ %61s /\n", "")
|
fmt.Fprintf(output, "/ %61s /\n", "")
|
||||||
fmt.Fprintf(output, "\\ %s \\\n", center(name+" (length + padded data)", 61))
|
fmt.Fprintf(output, "\\ %s \\\n", center(name+" (variable length)", 61))
|
||||||
fmt.Fprintf(output, "/ %61s /\n", "")
|
fmt.Fprintf(output, "/ %61s /\n", "")
|
||||||
|
fmt.Fprintln(output, line)
|
||||||
default:
|
default:
|
||||||
if f.IsSlice {
|
if f.IsSlice {
|
||||||
tn = "Zero or more " + tn + " Structures"
|
tn = "Zero or more " + tn + " Structures"
|
||||||
|
fmt.Fprintf(output, "/ %s /\n", center("", 61))
|
||||||
fmt.Fprintf(output, "\\ %s \\\n", center(tn, 61))
|
fmt.Fprintf(output, "\\ %s \\\n", center(tn, 61))
|
||||||
|
fmt.Fprintf(output, "/ %s /\n", center("", 61))
|
||||||
} else {
|
} else {
|
||||||
tn = tn + " Structure"
|
tn = tn + " Structure"
|
||||||
fmt.Fprintf(output, "/ %s /\n", center("", 61))
|
fmt.Fprintf(output, "/ %s /\n", center("", 61))
|
||||||
fmt.Fprintf(output, "\\ %s \\\n", center(tn, 61))
|
fmt.Fprintf(output, "\\ %s \\\n", center(tn, 61))
|
||||||
fmt.Fprintf(output, "/ %s /\n", center("", 61))
|
fmt.Fprintf(output, "/ %s /\n", center("", 61))
|
||||||
}
|
}
|
||||||
|
fmt.Fprintln(output, line)
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.IsSlice {
|
|
||||||
fmt.Fprintf(output, "/ %s /\n", center("", 61))
|
|
||||||
}
|
|
||||||
fmt.Fprintln(output, line)
|
|
||||||
}
|
}
|
||||||
fmt.Fprintln(output)
|
fmt.Fprintln(output)
|
||||||
fmt.Fprintln(output)
|
fmt.Fprintln(output)
|
||||||
@@ -496,9 +448,9 @@ func generateXdr(output io.Writer, s structInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch tn {
|
switch tn {
|
||||||
case "int8", "int16", "int32":
|
case "int16", "int32":
|
||||||
fmt.Fprintf(output, "\tint %s%s;\n", fn, suf)
|
fmt.Fprintf(output, "\tint %s%s;\n", fn, suf)
|
||||||
case "uint8", "uint16", "uint32":
|
case "uint16", "uint32":
|
||||||
fmt.Fprintf(output, "\tunsigned int %s%s;\n", fn, suf)
|
fmt.Fprintf(output, "\tunsigned int %s%s;\n", fn, suf)
|
||||||
case "int64":
|
case "int64":
|
||||||
fmt.Fprintf(output, "\thyper %s%s;\n", fn, suf)
|
fmt.Fprintf(output, "\thyper %s%s;\n", fn, suf)
|
||||||
@@ -506,7 +458,7 @@ func generateXdr(output io.Writer, s structInfo) {
|
|||||||
fmt.Fprintf(output, "\tunsigned hyper %s%s;\n", fn, suf)
|
fmt.Fprintf(output, "\tunsigned hyper %s%s;\n", fn, suf)
|
||||||
case "string":
|
case "string":
|
||||||
fmt.Fprintf(output, "\tstring %s<%s>;\n", fn, l)
|
fmt.Fprintf(output, "\tstring %s<%s>;\n", fn, l)
|
||||||
case "[]byte":
|
case "byte":
|
||||||
fmt.Fprintf(output, "\topaque %s<%s>;\n", fn, l)
|
fmt.Fprintf(output, "\topaque %s<%s>;\n", fn, l)
|
||||||
default:
|
default:
|
||||||
fmt.Fprintf(output, "\t%s %s%s;\n", tn, fn, suf)
|
fmt.Fprintf(output, "\t%s %s%s;\n", tn, fn, suf)
|
||||||
@@ -558,22 +510,6 @@ func main() {
|
|||||||
i := inspector(&structs)
|
i := inspector(&structs)
|
||||||
ast.Inspect(f, i)
|
ast.Inspect(f, i)
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
headerTpl.Execute(buf, map[string]string{"Package": f.Name.Name})
|
|
||||||
for _, s := range structs {
|
|
||||||
fmt.Fprintf(buf, "\n/*\n\n")
|
|
||||||
generateDiagram(buf, s)
|
|
||||||
generateXdr(buf, s)
|
|
||||||
fmt.Fprintf(buf, "*/\n")
|
|
||||||
generateCode(buf, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
bs, err := format.Source(buf.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
log.Print(buf.String())
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var output io.Writer = os.Stdout
|
var output io.Writer = os.Stdout
|
||||||
if *outputFile != "" {
|
if *outputFile != "" {
|
||||||
fd, err := os.Create(*outputFile)
|
fd, err := os.Create(*outputFile)
|
||||||
@@ -582,5 +518,13 @@ func main() {
|
|||||||
}
|
}
|
||||||
output = fd
|
output = fd
|
||||||
}
|
}
|
||||||
output.Write(bs)
|
|
||||||
|
headerTpl.Execute(output, map[string]string{"Package": f.Name.Name})
|
||||||
|
for _, s := range structs {
|
||||||
|
fmt.Fprintf(output, "\n/*\n\n")
|
||||||
|
generateDiagram(output, s)
|
||||||
|
generateXdr(output, s)
|
||||||
|
fmt.Fprintf(output, "*/\n")
|
||||||
|
generateCode(output, s)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-59
@@ -1,59 +0,0 @@
|
|||||||
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
|
|
||||||
// is governed by an MIT-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package xdr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
var padBytes = []byte{0, 0, 0}
|
|
||||||
|
|
||||||
// Pad returns the number of bytes that should be added to an item of length l
|
|
||||||
// bytes to conform to the XDR padding standard. This function is used by the
|
|
||||||
// generated marshalling code.
|
|
||||||
func Padding(l int) int {
|
|
||||||
d := l % 4
|
|
||||||
if d == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return 4 - d
|
|
||||||
}
|
|
||||||
|
|
||||||
// ElementSizeExceeded returns an error describing the violated size
|
|
||||||
// constraint. This function is used by the generated marshalling code.
|
|
||||||
func ElementSizeExceeded(field string, size, limit int) error {
|
|
||||||
return fmt.Errorf("%s exceeds size limit; %d > %d", field, size, limit)
|
|
||||||
}
|
|
||||||
|
|
||||||
type XDRSizer interface {
|
|
||||||
XDRSize() int
|
|
||||||
}
|
|
||||||
|
|
||||||
// SizeOfSlice returns the XDR encoded size of the given []T. Supported types
|
|
||||||
// for T are string, []byte and types implementing XDRSizer. SizeOfSlice
|
|
||||||
// panics if the parameter is not a slice or if T is not one of the supported
|
|
||||||
// types. This function is used by the generated marshalling code.
|
|
||||||
func SizeOfSlice(ss interface{}) int {
|
|
||||||
l := 0
|
|
||||||
switch ss := ss.(type) {
|
|
||||||
case []string:
|
|
||||||
for _, s := range ss {
|
|
||||||
l += 4 + len(s) + Padding(len(s))
|
|
||||||
}
|
|
||||||
|
|
||||||
case [][]byte:
|
|
||||||
for _, s := range ss {
|
|
||||||
l += 4 + len(s) + Padding(len(s))
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
v := reflect.ValueOf(ss)
|
|
||||||
for i := 0; i < v.Len(); i++ {
|
|
||||||
l += v.Index(i).Interface().(XDRSizer).XDRSize()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
|
||||||
|
// is governed by an MIT-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package xdr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
debug = len(os.Getenv("XDRTRACE")) > 0
|
||||||
|
dl = log.New(os.Stdout, "xdr: ", log.Lshortfile|log.Ltime|log.Lmicroseconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
const maxDebugBytes = 32
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
|
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
|
||||||
// is governed by an MIT-style license that can be found in the LICENSE file.
|
// is governed by an MIT-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// Package xdr implements an XDR (RFC 4506) marshaller/unmarshaller.
|
// Package xdr implements an XDR (RFC 4506) encoder/decoder.
|
||||||
package xdr
|
package xdr
|
||||||
|
|||||||
-123
@@ -1,123 +0,0 @@
|
|||||||
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
|
|
||||||
// is governed by an MIT-style license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package xdr
|
|
||||||
|
|
||||||
import "io"
|
|
||||||
|
|
||||||
// The Marshaller is a thin wrapper around a byte buffer. The buffer must be
|
|
||||||
// of sufficient size to hold the complete marshalled object, or an
|
|
||||||
// io.ErrShortBuffer error will result. The Marshal... methods don't
|
|
||||||
// individually return an error - the intention is that multiple fields are
|
|
||||||
// marshalled in rapid succession, followed by a check of the Error field on
|
|
||||||
// the Marshaller.
|
|
||||||
type Marshaller struct {
|
|
||||||
Data []byte
|
|
||||||
Error error
|
|
||||||
|
|
||||||
offset int
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalRaw copies the raw bytes to the buffer, without a size prefix or
|
|
||||||
// padding. This is suitable for appending data already in XDR format from
|
|
||||||
// another source.
|
|
||||||
func (m *Marshaller) MarshalRaw(bs []byte) {
|
|
||||||
if m.Error != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(m.Data) < m.offset+len(bs) {
|
|
||||||
m.Error = io.ErrShortBuffer
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
m.offset += copy(m.Data[m.offset:], bs)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalString appends the string to the buffer, with a size prefix and
|
|
||||||
// correct padding.
|
|
||||||
func (m *Marshaller) MarshalString(s string) {
|
|
||||||
if m.Error != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(m.Data) < m.offset+4+len(s)+Padding(len(s)) {
|
|
||||||
m.Error = io.ErrShortBuffer
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
m.MarshalUint32(uint32(len(s)))
|
|
||||||
m.offset += copy(m.Data[m.offset:], s)
|
|
||||||
m.offset += copy(m.Data[m.offset:], padBytes[:Padding(len(s))])
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalString appends the bytes to the buffer, with a size prefix and
|
|
||||||
// correct padding.
|
|
||||||
func (m *Marshaller) MarshalBytes(bs []byte) {
|
|
||||||
if m.Error != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(m.Data) < m.offset+4+len(bs)+Padding(len(bs)) {
|
|
||||||
m.Error = io.ErrShortBuffer
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
m.MarshalUint32(uint32(len(bs)))
|
|
||||||
m.offset += copy(m.Data[m.offset:], bs)
|
|
||||||
m.offset += copy(m.Data[m.offset:], padBytes[:Padding(len(bs))])
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalString appends the bool to the buffer, as an uint32.
|
|
||||||
func (m *Marshaller) MarshalBool(v bool) {
|
|
||||||
if v {
|
|
||||||
m.MarshalUint8(1)
|
|
||||||
} else {
|
|
||||||
m.MarshalUint8(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalString appends the uint8 to the buffer, as an uint32.
|
|
||||||
func (m *Marshaller) MarshalUint8(v uint8) {
|
|
||||||
m.MarshalUint32(uint32(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalString appends the uint16 to the buffer, as an uint32.
|
|
||||||
func (m *Marshaller) MarshalUint16(v uint16) {
|
|
||||||
m.MarshalUint32(uint32(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalString appends the uint32 to the buffer.
|
|
||||||
func (m *Marshaller) MarshalUint32(v uint32) {
|
|
||||||
if m.Error != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(m.Data) < m.offset+4 {
|
|
||||||
m.Error = io.ErrShortBuffer
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Data[m.offset+0] = byte(v >> 24)
|
|
||||||
m.Data[m.offset+1] = byte(v >> 16)
|
|
||||||
m.Data[m.offset+2] = byte(v >> 8)
|
|
||||||
m.Data[m.offset+3] = byte(v)
|
|
||||||
m.offset += 4
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalString appends the uint64 to the buffer.
|
|
||||||
func (m *Marshaller) MarshalUint64(v uint64) {
|
|
||||||
if m.Error != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(m.Data) < m.offset+8 {
|
|
||||||
m.Error = io.ErrShortBuffer
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Data[m.offset+0] = byte(v >> 56)
|
|
||||||
m.Data[m.offset+1] = byte(v >> 48)
|
|
||||||
m.Data[m.offset+2] = byte(v >> 40)
|
|
||||||
m.Data[m.offset+3] = byte(v >> 32)
|
|
||||||
m.Data[m.offset+4] = byte(v >> 24)
|
|
||||||
m.Data[m.offset+5] = byte(v >> 16)
|
|
||||||
m.Data[m.offset+6] = byte(v >> 8)
|
|
||||||
m.Data[m.offset+7] = byte(v)
|
|
||||||
m.offset += 8
|
|
||||||
}
|
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
|
||||||
|
// is governed by an MIT-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ipdr
|
||||||
|
|
||||||
|
package xdr
|
||||||
|
|
||||||
|
func pad(l int) int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
|
||||||
|
// is governed by an MIT-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !ipdr
|
||||||
|
|
||||||
|
package xdr
|
||||||
|
|
||||||
|
func pad(l int) int {
|
||||||
|
d := l % 4
|
||||||
|
if d == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 4 - d
|
||||||
|
}
|
||||||
+171
@@ -0,0 +1,171 @@
|
|||||||
|
// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
|
||||||
|
// All rights reserved. Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package xdr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Reader struct {
|
||||||
|
r io.Reader
|
||||||
|
err error
|
||||||
|
b [8]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewReader(r io.Reader) *Reader {
|
||||||
|
return &Reader{
|
||||||
|
r: r,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) ReadRaw(bs []byte) (int, error) {
|
||||||
|
if r.err != nil {
|
||||||
|
return 0, r.err
|
||||||
|
}
|
||||||
|
|
||||||
|
var n int
|
||||||
|
n, r.err = io.ReadFull(r.r, bs)
|
||||||
|
return n, r.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) ReadString() string {
|
||||||
|
return r.ReadStringMax(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) ReadStringMax(max int) string {
|
||||||
|
buf := r.ReadBytesMaxInto(max, nil)
|
||||||
|
bh := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
sh := reflect.StringHeader{
|
||||||
|
Data: bh.Data,
|
||||||
|
Len: bh.Len,
|
||||||
|
}
|
||||||
|
return *((*string)(unsafe.Pointer(&sh)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) ReadBytes() []byte {
|
||||||
|
return r.ReadBytesInto(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) ReadBytesMax(max int) []byte {
|
||||||
|
return r.ReadBytesMaxInto(max, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) ReadBytesInto(dst []byte) []byte {
|
||||||
|
return r.ReadBytesMaxInto(0, dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) ReadBytesMaxInto(max int, dst []byte) []byte {
|
||||||
|
if r.err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
l := int(r.ReadUint32())
|
||||||
|
if r.err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if l < 0 || max > 0 && l > max {
|
||||||
|
// l may be negative on 32 bit builds
|
||||||
|
r.err = ElementSizeExceeded("bytes field", l, max)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if fullLen := l + pad(l); fullLen > len(dst) {
|
||||||
|
dst = make([]byte, fullLen)
|
||||||
|
} else {
|
||||||
|
dst = dst[:fullLen]
|
||||||
|
}
|
||||||
|
|
||||||
|
var n int
|
||||||
|
n, r.err = io.ReadFull(r.r, dst)
|
||||||
|
if r.err != nil {
|
||||||
|
if debug {
|
||||||
|
dl.Printf("rd bytes (%d): %v", len(dst), r.err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
if n > maxDebugBytes {
|
||||||
|
dl.Printf("rd bytes (%d): %x...", len(dst), dst[:maxDebugBytes])
|
||||||
|
} else {
|
||||||
|
dl.Printf("rd bytes (%d): %x", len(dst), dst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst[:l]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) ReadBool() bool {
|
||||||
|
return r.ReadUint8() != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) ReadUint32() uint32 {
|
||||||
|
if r.err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_, r.err = io.ReadFull(r.r, r.b[:4])
|
||||||
|
if r.err != nil {
|
||||||
|
if debug {
|
||||||
|
dl.Printf("rd uint32: %v", r.err)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
v := uint32(r.b[3]) | uint32(r.b[2])<<8 | uint32(r.b[1])<<16 | uint32(r.b[0])<<24
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
dl.Printf("rd uint32=%d (0x%08x)", v, v)
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) ReadUint64() uint64 {
|
||||||
|
if r.err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_, r.err = io.ReadFull(r.r, r.b[:8])
|
||||||
|
if r.err != nil {
|
||||||
|
if debug {
|
||||||
|
dl.Printf("rd uint64: %v", r.err)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
v := uint64(r.b[7]) | uint64(r.b[6])<<8 | uint64(r.b[5])<<16 | uint64(r.b[4])<<24 |
|
||||||
|
uint64(r.b[3])<<32 | uint64(r.b[2])<<40 | uint64(r.b[1])<<48 | uint64(r.b[0])<<56
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
dl.Printf("rd uint64=%d (0x%016x)", v, v)
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
type XDRError struct {
|
||||||
|
op string
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e XDRError) Error() string {
|
||||||
|
return "xdr " + e.op + ": " + e.err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e XDRError) IsEOF() bool {
|
||||||
|
return e.err == io.EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) Error() error {
|
||||||
|
if r.err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return XDRError{"read", r.err}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ElementSizeExceeded(field string, size, limit int) error {
|
||||||
|
return fmt.Errorf("%s exceeds size limit; %d > %d", field, size, limit)
|
||||||
|
}
|
||||||
+49
@@ -0,0 +1,49 @@
|
|||||||
|
// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
|
||||||
|
// All rights reserved. Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ipdr
|
||||||
|
|
||||||
|
package xdr
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
func (r *Reader) ReadUint8() uint8 {
|
||||||
|
if r.err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_, r.err = io.ReadFull(r.r, r.b[:1])
|
||||||
|
if r.err != nil {
|
||||||
|
if debug {
|
||||||
|
dl.Printf("rd uint8: %v", r.err)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
dl.Printf("rd uint8=%d (0x%02x)", r.b[0], r.b[0])
|
||||||
|
}
|
||||||
|
return r.b[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) ReadUint16() uint16 {
|
||||||
|
if r.err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_, r.err = io.ReadFull(r.r, r.b[:2])
|
||||||
|
if r.err != nil {
|
||||||
|
if debug {
|
||||||
|
dl.Printf("rd uint16: %v", r.err)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
v := uint16(r.b[1]) | uint16(r.b[0])<<8
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
dl.Printf("rd uint16=%d (0x%04x)", v, v)
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
|
||||||
|
// All rights reserved. Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !ipdr
|
||||||
|
|
||||||
|
package xdr
|
||||||
|
|
||||||
|
func (r *Reader) ReadUint8() uint8 {
|
||||||
|
return uint8(r.ReadUint32())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) ReadUint16() uint16 {
|
||||||
|
return uint16(r.ReadUint32())
|
||||||
|
}
|
||||||
-147
@@ -1,147 +0,0 @@
|
|||||||
// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
|
|
||||||
// All rights reserved. Use of this source code is governed by an MIT-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package xdr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"reflect"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Unmarshaller struct {
|
|
||||||
Error error
|
|
||||||
Data []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *Unmarshaller) UnmarshalRaw(l int) []byte {
|
|
||||||
if u.Error != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if len(u.Data) < l {
|
|
||||||
u.Error = io.ErrUnexpectedEOF
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
v := u.Data[:l]
|
|
||||||
u.Data = u.Data[l:]
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *Unmarshaller) UnmarshalString() string {
|
|
||||||
return u.UnmarshalStringMax(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *Unmarshaller) UnmarshalStringMax(max int) string {
|
|
||||||
buf := u.UnmarshalBytesMax(max)
|
|
||||||
if len(buf) == 0 || u.Error != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
var v string
|
|
||||||
p := (*reflect.StringHeader)(unsafe.Pointer(&v))
|
|
||||||
p.Data = uintptr(unsafe.Pointer(&buf[0]))
|
|
||||||
p.Len = len(buf)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *Unmarshaller) UnmarshalBytes() []byte {
|
|
||||||
return u.UnmarshalBytesMax(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *Unmarshaller) UnmarshalBytesMax(max int) []byte {
|
|
||||||
if u.Error != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if len(u.Data) < 4 {
|
|
||||||
u.Error = io.ErrUnexpectedEOF
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
l := int(u.Data[3]) | int(u.Data[2])<<8 | int(u.Data[1])<<16 | int(u.Data[0])<<24
|
|
||||||
if l == 0 {
|
|
||||||
u.Data = u.Data[4:]
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if l < 0 || max > 0 && l > max {
|
|
||||||
// l may be negative on 32 bit builds
|
|
||||||
u.Error = ElementSizeExceeded("bytes field", l, max)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if len(u.Data) < l+4 {
|
|
||||||
u.Error = io.ErrUnexpectedEOF
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
v := u.Data[4 : 4+l]
|
|
||||||
u.Data = u.Data[4+l+Padding(l):]
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *Unmarshaller) UnmarshalBool() bool {
|
|
||||||
return u.UnmarshalUint8() != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *Unmarshaller) UnmarshalUint8() uint8 {
|
|
||||||
if u.Error != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if len(u.Data) < 4 {
|
|
||||||
u.Error = io.ErrUnexpectedEOF
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
v := uint8(u.Data[3])
|
|
||||||
u.Data = u.Data[4:]
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *Unmarshaller) UnmarshalUint16() uint16 {
|
|
||||||
if u.Error != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if len(u.Data) < 4 {
|
|
||||||
u.Error = io.ErrUnexpectedEOF
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
v := uint16(u.Data[3]) | uint16(u.Data[2])<<8
|
|
||||||
u.Data = u.Data[4:]
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *Unmarshaller) UnmarshalUint32() uint32 {
|
|
||||||
if u.Error != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if len(u.Data) < 4 {
|
|
||||||
u.Error = io.ErrUnexpectedEOF
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
v := uint32(u.Data[3]) | uint32(u.Data[2])<<8 | uint32(u.Data[1])<<16 | uint32(u.Data[0])<<24
|
|
||||||
u.Data = u.Data[4:]
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *Unmarshaller) UnmarshalUint64() uint64 {
|
|
||||||
if u.Error != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if len(u.Data) < 8 {
|
|
||||||
u.Error = io.ErrUnexpectedEOF
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
v := uint64(u.Data[7]) | uint64(u.Data[6])<<8 | uint64(u.Data[5])<<16 | uint64(u.Data[4])<<24 |
|
|
||||||
uint64(u.Data[3])<<32 | uint64(u.Data[2])<<40 | uint64(u.Data[1])<<48 | uint64(u.Data[0])<<56
|
|
||||||
u.Data = u.Data[8:]
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
+146
@@ -0,0 +1,146 @@
|
|||||||
|
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
|
||||||
|
// is governed by an MIT-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package xdr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
var padBytes = []byte{0, 0, 0}
|
||||||
|
|
||||||
|
type Writer struct {
|
||||||
|
w io.Writer
|
||||||
|
tot int
|
||||||
|
err error
|
||||||
|
b [8]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type AppendWriter []byte
|
||||||
|
|
||||||
|
func (w *AppendWriter) Write(bs []byte) (int, error) {
|
||||||
|
*w = append(*w, bs...)
|
||||||
|
return len(bs), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWriter(w io.Writer) *Writer {
|
||||||
|
return &Writer{
|
||||||
|
w: w,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Writer) WriteRaw(bs []byte) (int, error) {
|
||||||
|
if w.err != nil {
|
||||||
|
return 0, w.err
|
||||||
|
}
|
||||||
|
|
||||||
|
var n int
|
||||||
|
n, w.err = w.w.Write(bs)
|
||||||
|
return n, w.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Writer) WriteString(s string) (int, error) {
|
||||||
|
sh := *((*reflect.StringHeader)(unsafe.Pointer(&s)))
|
||||||
|
bh := reflect.SliceHeader{
|
||||||
|
Data: sh.Data,
|
||||||
|
Len: sh.Len,
|
||||||
|
Cap: sh.Len,
|
||||||
|
}
|
||||||
|
return w.WriteBytes(*(*[]byte)(unsafe.Pointer(&bh)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Writer) WriteBytes(bs []byte) (int, error) {
|
||||||
|
if w.err != nil {
|
||||||
|
return 0, w.err
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteUint32(uint32(len(bs)))
|
||||||
|
if w.err != nil {
|
||||||
|
return 0, w.err
|
||||||
|
}
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
if len(bs) > maxDebugBytes {
|
||||||
|
dl.Printf("wr bytes (%d): %x...", len(bs), bs[:maxDebugBytes])
|
||||||
|
} else {
|
||||||
|
dl.Printf("wr bytes (%d): %x", len(bs), bs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var l, n int
|
||||||
|
n, w.err = w.w.Write(bs)
|
||||||
|
l += n
|
||||||
|
|
||||||
|
if p := pad(len(bs)); w.err == nil && p > 0 {
|
||||||
|
n, w.err = w.w.Write(padBytes[:p])
|
||||||
|
l += n
|
||||||
|
}
|
||||||
|
|
||||||
|
w.tot += l
|
||||||
|
return l, w.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Writer) WriteBool(v bool) (int, error) {
|
||||||
|
if v {
|
||||||
|
return w.WriteUint8(1)
|
||||||
|
} else {
|
||||||
|
return w.WriteUint8(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Writer) WriteUint32(v uint32) (int, error) {
|
||||||
|
if w.err != nil {
|
||||||
|
return 0, w.err
|
||||||
|
}
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
dl.Printf("wr uint32=%d", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.b[0] = byte(v >> 24)
|
||||||
|
w.b[1] = byte(v >> 16)
|
||||||
|
w.b[2] = byte(v >> 8)
|
||||||
|
w.b[3] = byte(v)
|
||||||
|
|
||||||
|
var l int
|
||||||
|
l, w.err = w.w.Write(w.b[:4])
|
||||||
|
w.tot += l
|
||||||
|
return l, w.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Writer) WriteUint64(v uint64) (int, error) {
|
||||||
|
if w.err != nil {
|
||||||
|
return 0, w.err
|
||||||
|
}
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
dl.Printf("wr uint64=%d", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.b[0] = byte(v >> 56)
|
||||||
|
w.b[1] = byte(v >> 48)
|
||||||
|
w.b[2] = byte(v >> 40)
|
||||||
|
w.b[3] = byte(v >> 32)
|
||||||
|
w.b[4] = byte(v >> 24)
|
||||||
|
w.b[5] = byte(v >> 16)
|
||||||
|
w.b[6] = byte(v >> 8)
|
||||||
|
w.b[7] = byte(v)
|
||||||
|
|
||||||
|
var l int
|
||||||
|
l, w.err = w.w.Write(w.b[:8])
|
||||||
|
w.tot += l
|
||||||
|
return l, w.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Writer) Tot() int {
|
||||||
|
return w.tot
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Writer) Error() error {
|
||||||
|
if w.err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return XDRError{"write", w.err}
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
|
||||||
|
// is governed by an MIT-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ipdr
|
||||||
|
|
||||||
|
package xdr
|
||||||
|
|
||||||
|
func (w *Writer) WriteUint8(v uint8) (int, error) {
|
||||||
|
if w.err != nil {
|
||||||
|
return 0, w.err
|
||||||
|
}
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
dl.Printf("wr uint8=%d", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.b[0] = byte(v)
|
||||||
|
|
||||||
|
var l int
|
||||||
|
l, w.err = w.w.Write(w.b[:1])
|
||||||
|
w.tot += l
|
||||||
|
return l, w.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Writer) WriteUint16(v uint16) (int, error) {
|
||||||
|
if w.err != nil {
|
||||||
|
return 0, w.err
|
||||||
|
}
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
dl.Printf("wr uint8=%d", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.b[0] = byte(v >> 8)
|
||||||
|
w.b[1] = byte(v)
|
||||||
|
|
||||||
|
var l int
|
||||||
|
l, w.err = w.w.Write(w.b[:2])
|
||||||
|
w.tot += l
|
||||||
|
return l, w.err
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
|
||||||
|
// is governed by an MIT-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !ipdr
|
||||||
|
|
||||||
|
package xdr
|
||||||
|
|
||||||
|
func (w *Writer) WriteUint8(v uint8) (int, error) {
|
||||||
|
return w.WriteUint32(uint32(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Writer) WriteUint16(v uint16) (int, error) {
|
||||||
|
return w.WriteUint32(uint32(v))
|
||||||
|
}
|
||||||
-24
@@ -1,24 +0,0 @@
|
|||||||
Copyright 2012 Suryandaru Triandana <syndtr@gmail.com>
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
-201
@@ -1,201 +0,0 @@
|
|||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright {yyyy} {name of copyright owner}
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
* Neither the name of Google Inc. nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
Additional IP Rights Grant (Patents)
|
|
||||||
|
|
||||||
"This implementation" means the copyrightable works distributed by
|
|
||||||
Google as part of the Go project.
|
|
||||||
|
|
||||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
|
||||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
|
||||||
patent license to make, have made, use, offer to sell, sell, import,
|
|
||||||
transfer and otherwise run, modify and propagate the contents of this
|
|
||||||
implementation of Go, where such license applies only to those patent
|
|
||||||
claims, both currently owned or controlled by Google and acquired in
|
|
||||||
the future, licensable by Google that are necessarily infringed by this
|
|
||||||
implementation of Go. This grant does not include claims that would be
|
|
||||||
infringed only as a consequence of further modification of this
|
|
||||||
implementation. If you or your agent or exclusive licensee institute or
|
|
||||||
order or agree to the institution of patent litigation against any
|
|
||||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
|
||||||
that this implementation of Go or any code incorporated within this
|
|
||||||
implementation of Go constitutes direct or contributory patent
|
|
||||||
infringement, or inducement of patent infringement, then any patent
|
|
||||||
rights granted to you under this License for this implementation of Go
|
|
||||||
shall terminate as of the date such litigation is filed.
|
|
||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
* Neither the name of Google Inc. nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
Additional IP Rights Grant (Patents)
|
|
||||||
|
|
||||||
"This implementation" means the copyrightable works distributed by
|
|
||||||
Google as part of the Go project.
|
|
||||||
|
|
||||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
|
||||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
|
||||||
patent license to make, have made, use, offer to sell, sell, import,
|
|
||||||
transfer and otherwise run, modify and propagate the contents of this
|
|
||||||
implementation of Go, where such license applies only to those patent
|
|
||||||
claims, both currently owned or controlled by Google and acquired in
|
|
||||||
the future, licensable by Google that are necessarily infringed by this
|
|
||||||
implementation of Go. This grant does not include claims that would be
|
|
||||||
infringed only as a consequence of further modification of this
|
|
||||||
implementation. If you or your agent or exclusive licensee institute or
|
|
||||||
order or agree to the institution of patent litigation against any
|
|
||||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
|
||||||
that this implementation of Go or any code incorporated within this
|
|
||||||
implementation of Go constitutes direct or contributory patent
|
|
||||||
infringement, or inducement of patent infringement, then any patent
|
|
||||||
rights granted to you under this License for this implementation of Go
|
|
||||||
shall terminate as of the date such litigation is filed.
|
|
||||||
-156
@@ -1,156 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs defs_linux.go
|
|
||||||
|
|
||||||
// +build linux,mips64
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_ADDRFORM = 0x1
|
|
||||||
sysIPV6_2292PKTINFO = 0x2
|
|
||||||
sysIPV6_2292HOPOPTS = 0x3
|
|
||||||
sysIPV6_2292DSTOPTS = 0x4
|
|
||||||
sysIPV6_2292RTHDR = 0x5
|
|
||||||
sysIPV6_2292PKTOPTIONS = 0x6
|
|
||||||
sysIPV6_CHECKSUM = 0x7
|
|
||||||
sysIPV6_2292HOPLIMIT = 0x8
|
|
||||||
sysIPV6_NEXTHOP = 0x9
|
|
||||||
sysIPV6_FLOWINFO = 0xb
|
|
||||||
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x10
|
|
||||||
sysIPV6_MULTICAST_IF = 0x11
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0x12
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0x13
|
|
||||||
sysIPV6_ADD_MEMBERSHIP = 0x14
|
|
||||||
sysIPV6_DROP_MEMBERSHIP = 0x15
|
|
||||||
sysMCAST_JOIN_GROUP = 0x2a
|
|
||||||
sysMCAST_LEAVE_GROUP = 0x2d
|
|
||||||
sysMCAST_JOIN_SOURCE_GROUP = 0x2e
|
|
||||||
sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
|
|
||||||
sysMCAST_BLOCK_SOURCE = 0x2b
|
|
||||||
sysMCAST_UNBLOCK_SOURCE = 0x2c
|
|
||||||
sysMCAST_MSFILTER = 0x30
|
|
||||||
sysIPV6_ROUTER_ALERT = 0x16
|
|
||||||
sysIPV6_MTU_DISCOVER = 0x17
|
|
||||||
sysIPV6_MTU = 0x18
|
|
||||||
sysIPV6_RECVERR = 0x19
|
|
||||||
sysIPV6_V6ONLY = 0x1a
|
|
||||||
sysIPV6_JOIN_ANYCAST = 0x1b
|
|
||||||
sysIPV6_LEAVE_ANYCAST = 0x1c
|
|
||||||
|
|
||||||
sysIPV6_FLOWLABEL_MGR = 0x20
|
|
||||||
sysIPV6_FLOWINFO_SEND = 0x21
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = 0x22
|
|
||||||
sysIPV6_XFRM_POLICY = 0x23
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = 0x31
|
|
||||||
sysIPV6_PKTINFO = 0x32
|
|
||||||
sysIPV6_RECVHOPLIMIT = 0x33
|
|
||||||
sysIPV6_HOPLIMIT = 0x34
|
|
||||||
sysIPV6_RECVHOPOPTS = 0x35
|
|
||||||
sysIPV6_HOPOPTS = 0x36
|
|
||||||
sysIPV6_RTHDRDSTOPTS = 0x37
|
|
||||||
sysIPV6_RECVRTHDR = 0x38
|
|
||||||
sysIPV6_RTHDR = 0x39
|
|
||||||
sysIPV6_RECVDSTOPTS = 0x3a
|
|
||||||
sysIPV6_DSTOPTS = 0x3b
|
|
||||||
sysIPV6_RECVPATHMTU = 0x3c
|
|
||||||
sysIPV6_PATHMTU = 0x3d
|
|
||||||
sysIPV6_DONTFRAG = 0x3e
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = 0x42
|
|
||||||
sysIPV6_TCLASS = 0x43
|
|
||||||
|
|
||||||
sysIPV6_ADDR_PREFERENCES = 0x48
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_TMP = 0x1
|
|
||||||
sysIPV6_PREFER_SRC_PUBLIC = 0x2
|
|
||||||
sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
|
|
||||||
sysIPV6_PREFER_SRC_COA = 0x4
|
|
||||||
sysIPV6_PREFER_SRC_HOME = 0x400
|
|
||||||
sysIPV6_PREFER_SRC_CGA = 0x8
|
|
||||||
sysIPV6_PREFER_SRC_NONCGA = 0x800
|
|
||||||
|
|
||||||
sysIPV6_MINHOPCOUNT = 0x49
|
|
||||||
|
|
||||||
sysIPV6_ORIGDSTADDR = 0x4a
|
|
||||||
sysIPV6_RECVORIGDSTADDR = 0x4a
|
|
||||||
sysIPV6_TRANSPARENT = 0x4b
|
|
||||||
sysIPV6_UNICAST_IF = 0x4c
|
|
||||||
|
|
||||||
sysICMPV6_FILTER = 0x1
|
|
||||||
|
|
||||||
sysICMPV6_FILTER_BLOCK = 0x1
|
|
||||||
sysICMPV6_FILTER_PASS = 0x2
|
|
||||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
|
||||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
|
||||||
|
|
||||||
sysSizeofKernelSockaddrStorage = 0x80
|
|
||||||
sysSizeofSockaddrInet6 = 0x1c
|
|
||||||
sysSizeofInet6Pktinfo = 0x14
|
|
||||||
sysSizeofIPv6Mtuinfo = 0x20
|
|
||||||
sysSizeofIPv6FlowlabelReq = 0x20
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
sysSizeofGroupReq = 0x88
|
|
||||||
sysSizeofGroupSourceReq = 0x108
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysKernelSockaddrStorage struct {
|
|
||||||
Family uint16
|
|
||||||
X__data [126]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Family uint16
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysInet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo struct {
|
|
||||||
Addr sysSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6FlowlabelReq struct {
|
|
||||||
Dst [16]byte /* in6_addr */
|
|
||||||
Label uint32
|
|
||||||
Action uint8
|
|
||||||
Share uint8
|
|
||||||
Flags uint16
|
|
||||||
Expires uint16
|
|
||||||
Linger uint16
|
|
||||||
X__flr_pad uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Ifindex int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Group sysKernelSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupSourceReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Group sysKernelSockaddrStorage
|
|
||||||
Source sysKernelSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
Data [8]uint32
|
|
||||||
}
|
|
||||||
-156
@@ -1,156 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs defs_linux.go
|
|
||||||
|
|
||||||
// +build linux,mips64le
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_ADDRFORM = 0x1
|
|
||||||
sysIPV6_2292PKTINFO = 0x2
|
|
||||||
sysIPV6_2292HOPOPTS = 0x3
|
|
||||||
sysIPV6_2292DSTOPTS = 0x4
|
|
||||||
sysIPV6_2292RTHDR = 0x5
|
|
||||||
sysIPV6_2292PKTOPTIONS = 0x6
|
|
||||||
sysIPV6_CHECKSUM = 0x7
|
|
||||||
sysIPV6_2292HOPLIMIT = 0x8
|
|
||||||
sysIPV6_NEXTHOP = 0x9
|
|
||||||
sysIPV6_FLOWINFO = 0xb
|
|
||||||
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x10
|
|
||||||
sysIPV6_MULTICAST_IF = 0x11
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0x12
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0x13
|
|
||||||
sysIPV6_ADD_MEMBERSHIP = 0x14
|
|
||||||
sysIPV6_DROP_MEMBERSHIP = 0x15
|
|
||||||
sysMCAST_JOIN_GROUP = 0x2a
|
|
||||||
sysMCAST_LEAVE_GROUP = 0x2d
|
|
||||||
sysMCAST_JOIN_SOURCE_GROUP = 0x2e
|
|
||||||
sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
|
|
||||||
sysMCAST_BLOCK_SOURCE = 0x2b
|
|
||||||
sysMCAST_UNBLOCK_SOURCE = 0x2c
|
|
||||||
sysMCAST_MSFILTER = 0x30
|
|
||||||
sysIPV6_ROUTER_ALERT = 0x16
|
|
||||||
sysIPV6_MTU_DISCOVER = 0x17
|
|
||||||
sysIPV6_MTU = 0x18
|
|
||||||
sysIPV6_RECVERR = 0x19
|
|
||||||
sysIPV6_V6ONLY = 0x1a
|
|
||||||
sysIPV6_JOIN_ANYCAST = 0x1b
|
|
||||||
sysIPV6_LEAVE_ANYCAST = 0x1c
|
|
||||||
|
|
||||||
sysIPV6_FLOWLABEL_MGR = 0x20
|
|
||||||
sysIPV6_FLOWINFO_SEND = 0x21
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = 0x22
|
|
||||||
sysIPV6_XFRM_POLICY = 0x23
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = 0x31
|
|
||||||
sysIPV6_PKTINFO = 0x32
|
|
||||||
sysIPV6_RECVHOPLIMIT = 0x33
|
|
||||||
sysIPV6_HOPLIMIT = 0x34
|
|
||||||
sysIPV6_RECVHOPOPTS = 0x35
|
|
||||||
sysIPV6_HOPOPTS = 0x36
|
|
||||||
sysIPV6_RTHDRDSTOPTS = 0x37
|
|
||||||
sysIPV6_RECVRTHDR = 0x38
|
|
||||||
sysIPV6_RTHDR = 0x39
|
|
||||||
sysIPV6_RECVDSTOPTS = 0x3a
|
|
||||||
sysIPV6_DSTOPTS = 0x3b
|
|
||||||
sysIPV6_RECVPATHMTU = 0x3c
|
|
||||||
sysIPV6_PATHMTU = 0x3d
|
|
||||||
sysIPV6_DONTFRAG = 0x3e
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = 0x42
|
|
||||||
sysIPV6_TCLASS = 0x43
|
|
||||||
|
|
||||||
sysIPV6_ADDR_PREFERENCES = 0x48
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_TMP = 0x1
|
|
||||||
sysIPV6_PREFER_SRC_PUBLIC = 0x2
|
|
||||||
sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
|
|
||||||
sysIPV6_PREFER_SRC_COA = 0x4
|
|
||||||
sysIPV6_PREFER_SRC_HOME = 0x400
|
|
||||||
sysIPV6_PREFER_SRC_CGA = 0x8
|
|
||||||
sysIPV6_PREFER_SRC_NONCGA = 0x800
|
|
||||||
|
|
||||||
sysIPV6_MINHOPCOUNT = 0x49
|
|
||||||
|
|
||||||
sysIPV6_ORIGDSTADDR = 0x4a
|
|
||||||
sysIPV6_RECVORIGDSTADDR = 0x4a
|
|
||||||
sysIPV6_TRANSPARENT = 0x4b
|
|
||||||
sysIPV6_UNICAST_IF = 0x4c
|
|
||||||
|
|
||||||
sysICMPV6_FILTER = 0x1
|
|
||||||
|
|
||||||
sysICMPV6_FILTER_BLOCK = 0x1
|
|
||||||
sysICMPV6_FILTER_PASS = 0x2
|
|
||||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
|
||||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
|
||||||
|
|
||||||
sysSizeofKernelSockaddrStorage = 0x80
|
|
||||||
sysSizeofSockaddrInet6 = 0x1c
|
|
||||||
sysSizeofInet6Pktinfo = 0x14
|
|
||||||
sysSizeofIPv6Mtuinfo = 0x20
|
|
||||||
sysSizeofIPv6FlowlabelReq = 0x20
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
sysSizeofGroupReq = 0x88
|
|
||||||
sysSizeofGroupSourceReq = 0x108
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysKernelSockaddrStorage struct {
|
|
||||||
Family uint16
|
|
||||||
X__data [126]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Family uint16
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysInet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo struct {
|
|
||||||
Addr sysSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6FlowlabelReq struct {
|
|
||||||
Dst [16]byte /* in6_addr */
|
|
||||||
Label uint32
|
|
||||||
Action uint8
|
|
||||||
Share uint8
|
|
||||||
Flags uint16
|
|
||||||
Expires uint16
|
|
||||||
Linger uint16
|
|
||||||
X__flr_pad uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Ifindex int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Group sysKernelSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupSourceReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Group sysKernelSockaddrStorage
|
|
||||||
Source sysKernelSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
Data [8]uint32
|
|
||||||
}
|
|
||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
* Neither the name of Google Inc. nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
Additional IP Rights Grant (Patents)
|
|
||||||
|
|
||||||
"This implementation" means the copyrightable works distributed by
|
|
||||||
Google as part of the Go project.
|
|
||||||
|
|
||||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
|
||||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
|
||||||
patent license to make, have made, use, offer to sell, sell, import,
|
|
||||||
transfer and otherwise run, modify and propagate the contents of this
|
|
||||||
implementation of Go, where such license applies only to those patent
|
|
||||||
claims, both currently owned or controlled by Google and acquired in
|
|
||||||
the future, licensable by Google that are necessarily infringed by this
|
|
||||||
implementation of Go. This grant does not include claims that would be
|
|
||||||
infringed only as a consequence of further modification of this
|
|
||||||
implementation. If you or your agent or exclusive licensee institute or
|
|
||||||
order or agree to the institution of patent litigation against any
|
|
||||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
|
||||||
that this implementation of Go or any code incorporated within this
|
|
||||||
implementation of Go constitutes direct or contributory patent
|
|
||||||
infringement, or inducement of patent infringement, then any patent
|
|
||||||
rights granted to you under this License for this implementation of Go
|
|
||||||
shall terminate as of the date such litigation is filed.
|
|
||||||
@@ -41,6 +41,7 @@ KayoticSully <kayoticsully@gmail.com>
|
|||||||
kilburn <kilburn@la3.org>
|
kilburn <kilburn@la3.org>
|
||||||
kluppy <kluppy@going2blue.com>
|
kluppy <kluppy@going2blue.com>
|
||||||
kozec <kozec@kozec.com>
|
kozec <kozec@kozec.com>
|
||||||
|
kralo <max.schulze@online.de>
|
||||||
krozycki <rozycki.karol@gmail.com>
|
krozycki <rozycki.karol@gmail.com>
|
||||||
letiemble <laurent.etiemble@gmail.com> <laurent.etiemble@monobjc.net>
|
letiemble <laurent.etiemble@gmail.com> <laurent.etiemble@monobjc.net>
|
||||||
LordLandon <lordlandon@gmail.com>
|
LordLandon <lordlandon@gmail.com>
|
||||||
@@ -79,5 +80,6 @@ veeti <veeti.paananen@rojekti.fi>
|
|||||||
Vilbrekin <vilbrekin@gmail.com>
|
Vilbrekin <vilbrekin@gmail.com>
|
||||||
wkennington <william@wkennington.com>
|
wkennington <william@wkennington.com>
|
||||||
wsgcsysadmin <e.meitner@willystreet.coo>
|
wsgcsysadmin <e.meitner@willystreet.coo>
|
||||||
|
wweich <wweich@users.noreply.github.com> <wweich@gmx.de>
|
||||||
Zillode <zillode@zillode.be>
|
Zillode <zillode@zillode.be>
|
||||||
zukoo <fxgsell@gmail.com>
|
zukoo <fxgsell@gmail.com>
|
||||||
|
|||||||
@@ -188,7 +188,18 @@ func setup() {
|
|||||||
|
|
||||||
func test(pkg string) {
|
func test(pkg string) {
|
||||||
setBuildEnv()
|
setBuildEnv()
|
||||||
runPrint("go", "test", "-short", "-race", "-timeout", "60s", pkg)
|
useRace := runtime.GOARCH == "amd64"
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "darwin", "linux", "freebsd", "windows":
|
||||||
|
default:
|
||||||
|
useRace = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if useRace {
|
||||||
|
runPrint("go", "test", "-short", "-race", "-timeout", "60s", pkg)
|
||||||
|
} else {
|
||||||
|
runPrint("go", "test", "-short", "-timeout", "60s", pkg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func bench(pkg string) {
|
func bench(pkg string) {
|
||||||
|
|||||||
+12
-3
@@ -149,7 +149,16 @@ func (s *apiService) getListener(guiCfg config.GUIConfiguration) (net.Listener,
|
|||||||
|
|
||||||
func sendJSON(w http.ResponseWriter, jsonObject interface{}) {
|
func sendJSON(w http.ResponseWriter, jsonObject interface{}) {
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
json.NewEncoder(w).Encode(jsonObject)
|
// Marshalling might fail, in which case we should return a 500 with the
|
||||||
|
// actual error.
|
||||||
|
bs, err := json.Marshal(jsonObject)
|
||||||
|
if err != nil {
|
||||||
|
// This Marshal() can't fail though.
|
||||||
|
bs, _ = json.Marshal(map[string]string{"error": err.Error()})
|
||||||
|
http.Error(w, string(bs), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Write(bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *apiService) Serve() {
|
func (s *apiService) Serve() {
|
||||||
@@ -267,8 +276,8 @@ func (s *apiService) Serve() {
|
|||||||
defer s.fss.Stop()
|
defer s.fss.Stop()
|
||||||
s.fss.ServeBackground()
|
s.fss.ServeBackground()
|
||||||
|
|
||||||
l.Infoln("API listening on", listener.Addr())
|
l.Infoln("GUI and API listening on", listener.Addr())
|
||||||
l.Infoln("GUI URL is", guiCfg.URL())
|
l.Infoln("Access the GUI via the following URL:", guiCfg.URL())
|
||||||
if s.started != nil {
|
if s.started != nil {
|
||||||
// only set when run by the tests
|
// only set when run by the tests
|
||||||
close(s.started)
|
close(s.started)
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ var locations = map[locationEnum]string{
|
|||||||
locKeyFile: "${config}/key.pem",
|
locKeyFile: "${config}/key.pem",
|
||||||
locHTTPSCertFile: "${config}/https-cert.pem",
|
locHTTPSCertFile: "${config}/https-cert.pem",
|
||||||
locHTTPSKeyFile: "${config}/https-key.pem",
|
locHTTPSKeyFile: "${config}/https-key.pem",
|
||||||
locDatabase: "${config}/index-v0.13.0.db",
|
locDatabase: "${config}/index-v0.11.0.db",
|
||||||
locLogFile: "${config}/syncthing.log", // -logfile on Windows
|
locLogFile: "${config}/syncthing.log", // -logfile on Windows
|
||||||
locCsrfTokens: "${config}/csrftokens.txt",
|
locCsrfTokens: "${config}/csrftokens.txt",
|
||||||
locPanicLog: "${config}/panic-${timestamp}.log",
|
locPanicLog: "${config}/panic-${timestamp}.log",
|
||||||
|
|||||||
+22
-24
@@ -49,16 +49,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Version = "unknown-dev"
|
Version = "unknown-dev"
|
||||||
Codename = "Copper Cockroach"
|
Codename = "Beryllium Bedbug"
|
||||||
BuildStamp = "0"
|
BuildStamp = "0"
|
||||||
BuildDate time.Time
|
BuildDate time.Time
|
||||||
BuildHost = "unknown"
|
BuildHost = "unknown"
|
||||||
BuildUser = "unknown"
|
BuildUser = "unknown"
|
||||||
IsRelease bool
|
IsRelease bool
|
||||||
IsBeta bool
|
IsBeta bool
|
||||||
LongVersion string
|
LongVersion string
|
||||||
allowedVersionExp = regexp.MustCompile(`^v\d+\.\d+\.\d+(-[a-z0-9]+)*(\.\d+)*(\+\d+-g[0-9a-f]+)?(-dirty)?$`)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -90,8 +89,9 @@ const (
|
|||||||
func init() {
|
func init() {
|
||||||
if Version != "unknown-dev" {
|
if Version != "unknown-dev" {
|
||||||
// If not a generic dev build, version string should come from git describe
|
// If not a generic dev build, version string should come from git describe
|
||||||
if !allowedVersionExp.MatchString(Version) {
|
exp := regexp.MustCompile(`^v\d+\.\d+\.\d+(-[a-z0-9]+)*(\+\d+-g[0-9a-f]+)?(-dirty)?$`)
|
||||||
l.Fatalf("Invalid version string %q;\n\tdoes not match regexp %v", Version, allowedVersionExp)
|
if !exp.MatchString(Version) {
|
||||||
|
l.Fatalf("Invalid version string %q;\n\tdoes not match regexp %v", Version, exp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,7 +340,7 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
l.Fatalln("Upgrade:", err) // exits 1
|
l.Fatalln("Upgrade:", err) // exits 1
|
||||||
}
|
}
|
||||||
l.Infoln("Upgraded from", options.upgradeTo)
|
l.Okln("Upgraded from", options.upgradeTo)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,14 +464,14 @@ func performUpgrade(release upgrade.Release) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
l.Fatalln("Upgrade:", err)
|
l.Fatalln("Upgrade:", err)
|
||||||
}
|
}
|
||||||
l.Infof("Upgraded to %q", release.Tag)
|
l.Okf("Upgraded to %q", release.Tag)
|
||||||
} else {
|
} else {
|
||||||
l.Infoln("Attempting upgrade through running Syncthing...")
|
l.Infoln("Attempting upgrade through running Syncthing...")
|
||||||
err = upgradeViaRest()
|
err = upgradeViaRest()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Fatalln("Upgrade:", err)
|
l.Fatalln("Upgrade:", err)
|
||||||
}
|
}
|
||||||
l.Infoln("Syncthing upgrading")
|
l.Okln("Syncthing upgrading")
|
||||||
os.Exit(exitUpgrading)
|
os.Exit(exitUpgrading)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -640,7 +640,6 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
|
|||||||
|
|
||||||
dbFile := locations[locDatabase]
|
dbFile := locations[locDatabase]
|
||||||
ldb, err := db.Open(dbFile)
|
ldb, err := db.Open(dbFile)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Fatalln("Cannot open database:", err, "- Is another copy of Syncthing already running?")
|
l.Fatalln("Cannot open database:", err, "- Is another copy of Syncthing already running?")
|
||||||
}
|
}
|
||||||
@@ -852,7 +851,7 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
|
|||||||
|
|
||||||
mainService.Stop()
|
mainService.Stop()
|
||||||
|
|
||||||
l.Infoln("Exiting")
|
l.Okln("Exiting")
|
||||||
|
|
||||||
if runtimeOptions.cpuProfile {
|
if runtimeOptions.cpuProfile {
|
||||||
pprof.StopCPUProfile()
|
pprof.StopCPUProfile()
|
||||||
@@ -1171,13 +1170,12 @@ func autoUpgrade(cfg *config.Wrapper) {
|
|||||||
// suitable time after they have gone out of fashion.
|
// suitable time after they have gone out of fashion.
|
||||||
func cleanConfigDirectory() {
|
func cleanConfigDirectory() {
|
||||||
patterns := map[string]time.Duration{
|
patterns := map[string]time.Duration{
|
||||||
"panic-*.log": 7 * 24 * time.Hour, // keep panic logs for a week
|
"panic-*.log": 7 * 24 * time.Hour, // keep panic logs for a week
|
||||||
"audit-*.log": 7 * 24 * time.Hour, // keep audit logs for a week
|
"audit-*.log": 7 * 24 * time.Hour, // keep audit logs for a week
|
||||||
"index": 14 * 24 * time.Hour, // keep old index format for two weeks
|
"index": 14 * 24 * time.Hour, // keep old index format for two weeks
|
||||||
"index*.converted": 14 * 24 * time.Hour, // keep old converted indexes for two weeks
|
"config.xml.v*": 30 * 24 * time.Hour, // old config versions for a month
|
||||||
"config.xml.v*": 30 * 24 * time.Hour, // old config versions for a month
|
"*.idx.gz": 30 * 24 * time.Hour, // these should for sure no longer exist
|
||||||
"*.idx.gz": 30 * 24 * time.Hour, // these should for sure no longer exist
|
"backup-of-v0.8": 30 * 24 * time.Hour, // these neither
|
||||||
"backup-of-v0.8": 30 * 24 * time.Hour, // these neither
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for pat, dur := range patterns {
|
for pat, dur := range patterns {
|
||||||
|
|||||||
@@ -175,29 +175,3 @@ func TestShortIDCheck(t *testing.T) {
|
|||||||
t.Error("Should have gotten an error")
|
t.Error("Should have gotten an error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAllowedVersions(t *testing.T) {
|
|
||||||
testcases := []struct {
|
|
||||||
ver string
|
|
||||||
allowed bool
|
|
||||||
}{
|
|
||||||
{"v0.13.0", true},
|
|
||||||
{"v0.12.11+22-gabcdef0", true},
|
|
||||||
{"v0.13.0-beta0", true},
|
|
||||||
{"v0.13.0-beta47", true},
|
|
||||||
{"v0.13.0-beta47+1-gabcdef0", true},
|
|
||||||
{"v0.13.0-beta.0", true},
|
|
||||||
{"v0.13.0-beta.47", true},
|
|
||||||
{"v0.13.0-beta.0+1-gabcdef0", true},
|
|
||||||
{"v0.13.0-beta.47+1-gabcdef0", true},
|
|
||||||
{"v0.13.0-some-weird-but-allowed-tag", true},
|
|
||||||
{"v0.13.0-not.allowed.to.do.this", false},
|
|
||||||
{"v0.13.0+not.allowed.to.do.this", false},
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, c := range testcases {
|
|
||||||
if allowed := allowedVersionExp.MatchString(c.ver); allowed != c.allowed {
|
|
||||||
t.Errorf("%d: incorrect result %v != %v for %q", i, allowed, c.allowed, c.ver)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Vendored
+11
-3
@@ -1,8 +1,16 @@
|
|||||||
Package: syncthing
|
Package: syncthing
|
||||||
|
Version: {{.version}}
|
||||||
|
Priority: optional
|
||||||
|
Section: net
|
||||||
Architecture: {{.arch}}
|
Architecture: {{.arch}}
|
||||||
Depends: libc6, procps
|
Depends: libc6, procps
|
||||||
Version: {{.version}}
|
Homepage: https://syncthing.net/
|
||||||
Maintainer: Syncthing Release Management <release@syncthing.net>
|
Maintainer: Syncthing Release Management <release@syncthing.net>
|
||||||
Description: Open Source Continuous File Synchronization
|
Description: Open Source Continuous File Synchronization
|
||||||
Syncthing does bidirectional synchronization of files between two or
|
Syncthing is an application that lets you synchronize your files across
|
||||||
more computers.
|
multiple devices. This means the creation, modification or deletion of files
|
||||||
|
on one machine will automatically be replicated to your other devices. We
|
||||||
|
believe your data is your data alone and you deserve to choose where it is
|
||||||
|
stored. Therefore Syncthing does not upload your data to the cloud but
|
||||||
|
exchanges your data across your machines as soon as they are online at the
|
||||||
|
same time.
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Restart Syncthing after resume
|
||||||
|
After=suspend.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/bin/pkill -HUP -x syncthing
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=suspend.target
|
||||||
@@ -437,7 +437,7 @@ code.ng-binding{
|
|||||||
}
|
}
|
||||||
|
|
||||||
.well, .form-control[readonly="readonly"] { /* read-only fields*/
|
.well, .form-control[readonly="readonly"] { /* read-only fields*/
|
||||||
color: #444 !important;
|
color: #666 !important;
|
||||||
border-color: #444 !important;
|
border-color: #444 !important;
|
||||||
background-color: #111 !important;
|
background-color: #111 !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ ul+h5 {
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
.panel-title a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
identicon {
|
identicon {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -246,11 +249,32 @@ ul.three-columns li, ul.two-columns li {
|
|||||||
/** Footer nav on small devices **/
|
/** Footer nav on small devices **/
|
||||||
|
|
||||||
@media (max-width: 1199px) {
|
@media (max-width: 1199px) {
|
||||||
|
/* Stay at the end of the page, with space reserved for the footer
|
||||||
|
usually taking up two rows. */
|
||||||
|
|
||||||
|
html {
|
||||||
|
position: relative;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
padding-bottom: 0;
|
padding-bottom: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-fixed-bottom {
|
.navbar-fixed-bottom {
|
||||||
position: static;
|
position: absolute;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
/* Layout after the normal contents, as this is when the footer switches
|
||||||
|
to a vertical layout. */
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-fixed-bottom {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Добави",
|
"Add": "Добави",
|
||||||
"Add Device": "Добави устройство",
|
"Add Device": "Добави устройство",
|
||||||
"Add Folder": "Добави папка",
|
"Add Folder": "Добави папка",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Добави нова папка?",
|
"Add new folder?": "Добави нова папка?",
|
||||||
"Address": "Адрес",
|
"Address": "Адрес",
|
||||||
"Addresses": "Адреси",
|
"Addresses": "Адреси",
|
||||||
"Advanced": "Допълнителни",
|
"Advanced": "Допълнителни",
|
||||||
"Advanced Configuration": "Допълнителни настройки",
|
"Advanced Configuration": "Допълнителни настройки",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Всички данни",
|
"All Data": "Всички данни",
|
||||||
"Allow Anonymous Usage Reporting?": "Разреши анонимно докладване за употребата на програмата?",
|
"Allow Anonymous Usage Reporting?": "Разреши анонимно докладване за употребата на програмата?",
|
||||||
"Alphabetic": "Азбучен ред",
|
"Alphabetic": "Азбучен ред",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Грешка при свързването",
|
"Connection Error": "Грешка при свързването",
|
||||||
"Copied from elsewhere": "Копиране от някъде другаде",
|
"Copied from elsewhere": "Копиране от някъде другаде",
|
||||||
"Copied from original": "Копиран от оригинала",
|
"Copied from original": "Копиран от оригинала",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Всички правата запазени © 2015 Сътрудници:",
|
"Copyright © 2015 the following Contributors:": "Всички правата запазени © 2015 Сътрудници:",
|
||||||
"Danger!": "Опасност!",
|
"Danger!": "Опасност!",
|
||||||
"Delete": "Изтрий",
|
"Delete": "Изтрий",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Защитава файловете от промени направени на други устройства, но промените направени на това устройство ще бъдат синхронизирани с останалите устройства.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Защитава файловете от промени направени на други устройства, но промените направени на това устройство ще бъдат синхронизирани с останалите устройства.",
|
||||||
"Folder": "Папка",
|
"Folder": "Папка",
|
||||||
"Folder ID": "Идентификатор на папката",
|
"Folder ID": "Идентификатор на папката",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Главна папка",
|
"Folder Master": "Главна папка",
|
||||||
"Folder Path": "Път до папката",
|
"Folder Path": "Път до папката",
|
||||||
"Folders": "Папки",
|
"Folders": "Папки",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "ОК",
|
"OK": "ОК",
|
||||||
"Off": "Изключено",
|
"Off": "Изключено",
|
||||||
"Oldest First": "Първо най-старите",
|
"Oldest First": "Първо най-старите",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Настройки",
|
"Options": "Настройки",
|
||||||
"Out of Sync": "Несинхронизирано",
|
"Out of Sync": "Несинхронизирано",
|
||||||
"Out of Sync Items": "Несинхронизирани елементи",
|
"Out of Sync Items": "Несинхронизирани елементи",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Препратено през",
|
"Relayed via": "Препратено през",
|
||||||
"Relays": "Препращачи",
|
"Relays": "Препращачи",
|
||||||
"Release Notes": "Бележки по обновяването",
|
"Release Notes": "Бележки по обновяването",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Премахни",
|
"Remove": "Премахни",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Сканирай повторно",
|
"Rescan": "Сканирай повторно",
|
||||||
"Rescan All": "Сканирай повторно всички",
|
"Rescan All": "Сканирай повторно всички",
|
||||||
"Rescan Interval": "Интервал за повторно сканиране",
|
"Rescan Interval": "Интервал за повторно сканиране",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "Ограничението на скоростта трябва да бъде положително число (0: неограничено)",
|
"The rate limit must be a non-negative number (0: no limit)": "Ограничението на скоростта трябва да бъде положително число (0: неограничено)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Интервала на сканиране трябва да бъде не отрицателно число в секунди.",
|
"The rescan interval must be a non-negative number of seconds.": "Интервала на сканиране трябва да бъде не отрицателно число в секунди.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Ще бъдат спрени и автоматично синхронизирани, когато грешката бъде оправена.",
|
"They are retried automatically and will be synced when the error is resolved.": "Ще бъдат спрени и автоматично синхронизирани, когато грешката бъде оправена.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Това дава лесен достъп на хакери да разглеждат и променят всякакви файлове на компютъра Ви.",
|
"This can easily give hackers access to read and change any files on your computer.": "Това дава лесен достъп на хакери да разглеждат и променят всякакви файлове на компютъра Ви.",
|
||||||
"This is a major version upgrade.": "Това е нова основна версия.",
|
"This is a major version upgrade.": "Това е нова основна версия.",
|
||||||
"Trash Can File Versioning": "Само на файловете в кошчето",
|
"Trash Can File Versioning": "Само на файловете в кошчето",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Версия",
|
"Version": "Версия",
|
||||||
"Versions Path": "Път до версиите",
|
"Versions Path": "Път до версиите",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Версиите биват изтривани автоматично, когато са по-стари от максималната възраст или надминават броя файлове разрешени в даден интервал.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Версиите биват изтривани автоматично, когато са по-стари от максималната възраст или надминават броя файлове разрешени в даден интервал.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Когато добавяш ново устройство помни, че твоето устройство също трябва да бъде добавено от другата страна.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Когато добавяш ново устройство помни, че твоето устройство също трябва да бъде добавено от другата страна.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Когато добавяш нов идентификатор на папка помни, че той се използва за свързване на папките на различни устройства. Главни/малки букви са от значение и трябва да са еднакви на всички устройства.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Когато добавяш нов идентификатор на папка помни, че той се използва за свързване на папките на различни устройства. Главни/малки букви са от значение и трябва да са еднакви на всички устройства.",
|
||||||
"Yes": "Да",
|
"Yes": "Да",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "дни",
|
"days": "дни",
|
||||||
"full documentation": "пълна документация",
|
"full documentation": "пълна документация",
|
||||||
"items": "елемента",
|
"items": "елемента",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} желае да сподели папка \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} желае да сподели папка \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Afegir",
|
"Add": "Afegir",
|
||||||
"Add Device": "Afegir dispositiu",
|
"Add Device": "Afegir dispositiu",
|
||||||
"Add Folder": "Afegir carpeta",
|
"Add Folder": "Afegir carpeta",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Afegir nova carpeta?",
|
"Add new folder?": "Afegir nova carpeta?",
|
||||||
"Address": "Adreça",
|
"Address": "Adreça",
|
||||||
"Addresses": "Adreces",
|
"Addresses": "Adreces",
|
||||||
"Advanced": "Avançat",
|
"Advanced": "Avançat",
|
||||||
"Advanced Configuration": "Configuració Avançada",
|
"Advanced Configuration": "Configuració Avançada",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Totes les dades",
|
"All Data": "Totes les dades",
|
||||||
"Allow Anonymous Usage Reporting?": "Permetre l'enviament anònim d'informes d'ús?",
|
"Allow Anonymous Usage Reporting?": "Permetre l'enviament anònim d'informes d'ús?",
|
||||||
"Alphabetic": "Alfabètic",
|
"Alphabetic": "Alfabètic",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Error de connexió",
|
"Connection Error": "Error de connexió",
|
||||||
"Copied from elsewhere": "Copiat d'un altre lloc",
|
"Copied from elsewhere": "Copiat d'un altre lloc",
|
||||||
"Copied from original": "Copiat de l'original",
|
"Copied from original": "Copiat de l'original",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 els següents col·laboradors:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 els següents col·laboradors:",
|
||||||
"Danger!": "Perill!",
|
"Danger!": "Perill!",
|
||||||
"Delete": "Esborrar",
|
"Delete": "Esborrar",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Els fitxers estan protegits de canvis fets per altres dispositius, però els canvis fets en aquest dispositiu seran enviats a la resta del cluster.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Els fitxers estan protegits de canvis fets per altres dispositius, però els canvis fets en aquest dispositiu seran enviats a la resta del cluster.",
|
||||||
"Folder": "Carpeta",
|
"Folder": "Carpeta",
|
||||||
"Folder ID": "ID de carpeta",
|
"Folder ID": "ID de carpeta",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Carpeta mestra",
|
"Folder Master": "Carpeta mestra",
|
||||||
"Folder Path": "Camí de carpeta",
|
"Folder Path": "Camí de carpeta",
|
||||||
"Folders": "Carpetes",
|
"Folders": "Carpetes",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Desactivar",
|
"Off": "Desactivar",
|
||||||
"Oldest First": "Més antic primer",
|
"Oldest First": "Més antic primer",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Opcions",
|
"Options": "Opcions",
|
||||||
"Out of Sync": "Fora de sincronia",
|
"Out of Sync": "Fora de sincronia",
|
||||||
"Out of Sync Items": "Arxius encara no sincronitzats",
|
"Out of Sync Items": "Arxius encara no sincronitzats",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Retransmés a través",
|
"Relayed via": "Retransmés a través",
|
||||||
"Relays": "Repetidors",
|
"Relays": "Repetidors",
|
||||||
"Release Notes": "Notes de llançament",
|
"Release Notes": "Notes de llançament",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Esborrar",
|
"Remove": "Esborrar",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Re-escanejar",
|
"Rescan": "Re-escanejar",
|
||||||
"Rescan All": "Re-escanejar tot",
|
"Rescan All": "Re-escanejar tot",
|
||||||
"Rescan Interval": "Interval de re-escaneig",
|
"Rescan Interval": "Interval de re-escaneig",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "El límit de velocitat ha de ser un nombre positiu (0: sense límit)",
|
"The rate limit must be a non-negative number (0: no limit)": "El límit de velocitat ha de ser un nombre positiu (0: sense límit)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "El interval de re-escaneig ha der ser un nombre positiu de segons.",
|
"The rescan interval must be a non-negative number of seconds.": "El interval de re-escaneig ha der ser un nombre positiu de segons.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Són reintentats automàticament i seran sincronitzats quan l'error estigui resolt.",
|
"They are retried automatically and will be synced when the error is resolved.": "Són reintentats automàticament i seran sincronitzats quan l'error estigui resolt.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Això pot donar facilment accés a hackers per llegir i canviar qualsevol fitxer del teu ordinador.",
|
"This can easily give hackers access to read and change any files on your computer.": "Això pot donar facilment accés a hackers per llegir i canviar qualsevol fitxer del teu ordinador.",
|
||||||
"This is a major version upgrade.": "Aquesta és una actualització de versió major.",
|
"This is a major version upgrade.": "Aquesta és una actualització de versió major.",
|
||||||
"Trash Can File Versioning": "Paperera de versionat de fitxers",
|
"Trash Can File Versioning": "Paperera de versionat de fitxers",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Versió",
|
"Version": "Versió",
|
||||||
"Versions Path": "Carpeta de les Versions",
|
"Versions Path": "Carpeta de les Versions",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Les versions son automàticament eliminades si son més antigues que el màxim d'antiguitat o si excedeixen del nombre de fitxers permesos en un interval.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Les versions son automàticament eliminades si son més antigues que el màxim d'antiguitat o si excedeixen del nombre de fitxers permesos en un interval.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Quan s'afegeix un nou dispositiu, recorda que aquest dispositiu tambè s'ha d'afegir a l'altre banda.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Quan s'afegeix un nou dispositiu, recorda que aquest dispositiu tambè s'ha d'afegir a l'altre banda.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Quan s'afegeix una nova carpeta recorda que el ID d'aquesta s'utilitza per lligar repositoris entre els dispositius. Es distingeix entre majúscules i minúscules i ha de ser exactament iguals entre tots els dispositius.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Quan s'afegeix una nova carpeta recorda que el ID d'aquesta s'utilitza per lligar repositoris entre els dispositius. Es distingeix entre majúscules i minúscules i ha de ser exactament iguals entre tots els dispositius.",
|
||||||
"Yes": "Si",
|
"Yes": "Si",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "dies",
|
"days": "dies",
|
||||||
"full documentation": "documentació sencera",
|
"full documentation": "documentació sencera",
|
||||||
"items": "Elements",
|
"items": "Elements",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} vol compartir la carpeta \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} vol compartir la carpeta \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Afegir",
|
"Add": "Afegir",
|
||||||
"Add Device": "Afegir dispositiu",
|
"Add Device": "Afegir dispositiu",
|
||||||
"Add Folder": "Afegir carpeta",
|
"Add Folder": "Afegir carpeta",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Afegir nova carpeta?",
|
"Add new folder?": "Afegir nova carpeta?",
|
||||||
"Address": "Direcció",
|
"Address": "Direcció",
|
||||||
"Addresses": "Direccions",
|
"Addresses": "Direccions",
|
||||||
"Advanced": "Avançat",
|
"Advanced": "Avançat",
|
||||||
"Advanced Configuration": "Configuració avançada",
|
"Advanced Configuration": "Configuració avançada",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Totes les dades",
|
"All Data": "Totes les dades",
|
||||||
"Allow Anonymous Usage Reporting?": "Permetre informes d'ús anònim?",
|
"Allow Anonymous Usage Reporting?": "Permetre informes d'ús anònim?",
|
||||||
"Alphabetic": "Alfabètic",
|
"Alphabetic": "Alfabètic",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Error de connexió",
|
"Connection Error": "Error de connexió",
|
||||||
"Copied from elsewhere": "Copiat de qualsevol lloc",
|
"Copied from elsewhere": "Copiat de qualsevol lloc",
|
||||||
"Copied from original": "Copiat de l'original",
|
"Copied from original": "Copiat de l'original",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 els següents Col·laboradors:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 els següents Col·laboradors:",
|
||||||
"Danger!": "Perill!",
|
"Danger!": "Perill!",
|
||||||
"Delete": "Esborrar",
|
"Delete": "Esborrar",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Els fitxers són protegits dels canvis fets en altres dispositius, però els canvis fets en aquest dispositiu seràn enviats a la resta del grup (cluster).",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Els fitxers són protegits dels canvis fets en altres dispositius, però els canvis fets en aquest dispositiu seràn enviats a la resta del grup (cluster).",
|
||||||
"Folder": "Carpeta",
|
"Folder": "Carpeta",
|
||||||
"Folder ID": "ID de carpeta",
|
"Folder ID": "ID de carpeta",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Carpeta principal",
|
"Folder Master": "Carpeta principal",
|
||||||
"Folder Path": "Ruta de la carpeta",
|
"Folder Path": "Ruta de la carpeta",
|
||||||
"Folders": "Carpetes",
|
"Folders": "Carpetes",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Off",
|
"Off": "Off",
|
||||||
"Oldest First": "El més vell primer",
|
"Oldest First": "El més vell primer",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Opcions",
|
"Options": "Opcions",
|
||||||
"Out of Sync": "Sense sincronització",
|
"Out of Sync": "Sense sincronització",
|
||||||
"Out of Sync Items": "Dispositius sense sincronitzar",
|
"Out of Sync Items": "Dispositius sense sincronitzar",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Transmitit via",
|
"Relayed via": "Transmitit via",
|
||||||
"Relays": "Transmissions",
|
"Relays": "Transmissions",
|
||||||
"Release Notes": "Notes de la versió",
|
"Release Notes": "Notes de la versió",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Eliminar",
|
"Remove": "Eliminar",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Tornar a buscar",
|
"Rescan": "Tornar a buscar",
|
||||||
"Rescan All": "Tornar a buscar tot",
|
"Rescan All": "Tornar a buscar tot",
|
||||||
"Rescan Interval": "Interval de nova busca",
|
"Rescan Interval": "Interval de nova busca",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "El llímit del ritme deu ser un nombre no negatiu (0: sense llímit)",
|
"The rate limit must be a non-negative number (0: no limit)": "El llímit del ritme deu ser un nombre no negatiu (0: sense llímit)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "L'interval de reescaneig deu ser un nombre positiu de segons.",
|
"The rescan interval must be a non-negative number of seconds.": "L'interval de reescaneig deu ser un nombre positiu de segons.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Es reintenta automàticament i es sincronitzaràn quant el resolga l'error.",
|
"They are retried automatically and will be synced when the error is resolved.": "Es reintenta automàticament i es sincronitzaràn quant el resolga l'error.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Açò pot donar accés fàcilment als hackers per a llegir i canviar qualsevol fitxer al teu ordinador.",
|
"This can easily give hackers access to read and change any files on your computer.": "Açò pot donar accés fàcilment als hackers per a llegir i canviar qualsevol fitxer al teu ordinador.",
|
||||||
"This is a major version upgrade.": "Aquesta és una actualització important de la versió.",
|
"This is a major version upgrade.": "Aquesta és una actualització important de la versió.",
|
||||||
"Trash Can File Versioning": "Versionat d'arxius de la paperera",
|
"Trash Can File Versioning": "Versionat d'arxius de la paperera",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Versió",
|
"Version": "Versió",
|
||||||
"Versions Path": "Ruta de les versions",
|
"Versions Path": "Ruta de les versions",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Les versions s'esborren automàticament si són més antigues que l'edat màxima o excedixen el nombre de fitxer permesos en un interval.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Les versions s'esborren automàticament si són més antigues que l'edat màxima o excedixen el nombre de fitxer permesos en un interval.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Quant s'afig un nou dispositiu, hi ha que tindre en compte que aquest dispositiu deu ser afegit també en l'altre costat.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Quant s'afig un nou dispositiu, hi ha que tindre en compte que aquest dispositiu deu ser afegit també en l'altre costat.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Quant s'afig una nova carpeta, hi ha que tindre en compte que l'ID de la carpeta s'utilitza per a juntar les carpetes entre dispositius. Són sensibles a les majúscules i deuen coincidir exactament entre tots els dispositius.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Quant s'afig una nova carpeta, hi ha que tindre en compte que l'ID de la carpeta s'utilitza per a juntar les carpetes entre dispositius. Són sensibles a les majúscules i deuen coincidir exactament entre tots els dispositius.",
|
||||||
"Yes": "Sí",
|
"Yes": "Sí",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "dies",
|
"days": "dies",
|
||||||
"full documentation": "Documentació completa",
|
"full documentation": "Documentació completa",
|
||||||
"items": "Elements",
|
"items": "Elements",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} vol compartit la carpeta \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} vol compartit la carpeta \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Přidat",
|
"Add": "Přidat",
|
||||||
"Add Device": "Přidat přístroj",
|
"Add Device": "Přidat přístroj",
|
||||||
"Add Folder": "Přidat adresář",
|
"Add Folder": "Přidat adresář",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Přidat nový adresář?",
|
"Add new folder?": "Přidat nový adresář?",
|
||||||
"Address": "Adresa",
|
"Address": "Adresa",
|
||||||
"Addresses": "Adresy",
|
"Addresses": "Adresy",
|
||||||
"Advanced": "Pokročilé",
|
"Advanced": "Pokročilé",
|
||||||
"Advanced Configuration": "Pokročilá nastavení",
|
"Advanced Configuration": "Pokročilá nastavení",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Všechna data",
|
"All Data": "Všechna data",
|
||||||
"Allow Anonymous Usage Reporting?": "Povolit anonymní hlášení o používání?",
|
"Allow Anonymous Usage Reporting?": "Povolit anonymní hlášení o používání?",
|
||||||
"Alphabetic": "Abecedně",
|
"Alphabetic": "Abecedně",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Chyba připojení",
|
"Connection Error": "Chyba připojení",
|
||||||
"Copied from elsewhere": "Zkopírováno odjinud",
|
"Copied from elsewhere": "Zkopírováno odjinud",
|
||||||
"Copied from original": "Zkopírováno z originálu",
|
"Copied from original": "Zkopírováno z originálu",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 následující přispěvatelé:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 následující přispěvatelé:",
|
||||||
"Danger!": "Pozor!",
|
"Danger!": "Pozor!",
|
||||||
"Delete": "Smazat",
|
"Delete": "Smazat",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Soubory jsou chráněny před změnami na ostatních přístrojích, ale změny provedené z tohoto přístroje budou rozeslány na zbytek clusteru.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Soubory jsou chráněny před změnami na ostatních přístrojích, ale změny provedené z tohoto přístroje budou rozeslány na zbytek clusteru.",
|
||||||
"Folder": "Adresář",
|
"Folder": "Adresář",
|
||||||
"Folder ID": "ID adresáře",
|
"Folder ID": "ID adresáře",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Master adresář",
|
"Folder Master": "Master adresář",
|
||||||
"Folder Path": "Cesta k adresáři",
|
"Folder Path": "Cesta k adresáři",
|
||||||
"Folders": "Adresáře",
|
"Folders": "Adresáře",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Vypnuta",
|
"Off": "Vypnuta",
|
||||||
"Oldest First": "Od nejstaršího",
|
"Oldest First": "Od nejstaršího",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Nastavení",
|
"Options": "Nastavení",
|
||||||
"Out of Sync": "Nesesynchronizováno",
|
"Out of Sync": "Nesesynchronizováno",
|
||||||
"Out of Sync Items": "Nesesynchronizované položky",
|
"Out of Sync Items": "Nesesynchronizované položky",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Přenášené přes",
|
"Relayed via": "Přenášené přes",
|
||||||
"Relays": "Přenašeče",
|
"Relays": "Přenašeče",
|
||||||
"Release Notes": "Poznámky k vydání",
|
"Release Notes": "Poznámky k vydání",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Odstranit",
|
"Remove": "Odstranit",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Opakovat skenování",
|
"Rescan": "Opakovat skenování",
|
||||||
"Rescan All": "Opakovat skenování všech",
|
"Rescan All": "Opakovat skenování všech",
|
||||||
"Rescan Interval": "Interval opakování skenování",
|
"Rescan Interval": "Interval opakování skenování",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "Limit rychlosti musí být nezáporné číslo (0: bez limitu)",
|
"The rate limit must be a non-negative number (0: no limit)": "Limit rychlosti musí být nezáporné číslo (0: bez limitu)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Interval opakování skenování musí být pozitivní číslo.",
|
"The rescan interval must be a non-negative number of seconds.": "Interval opakování skenování musí být pozitivní číslo.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Nové pokusy o synchronizaci budou probíhat automaticky a položky budou synchronizovány jakmile bude chyba odstraněna.",
|
"They are retried automatically and will be synced when the error is resolved.": "Nové pokusy o synchronizaci budou probíhat automaticky a položky budou synchronizovány jakmile bude chyba odstraněna.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "To může útočníkům jednoduše povolit čtení a úpravy souborů na vašem přístroji. ",
|
"This can easily give hackers access to read and change any files on your computer.": "To může útočníkům jednoduše povolit čtení a úpravy souborů na vašem přístroji. ",
|
||||||
"This is a major version upgrade.": "Toto je důležitá aktualizace.",
|
"This is a major version upgrade.": "Toto je důležitá aktualizace.",
|
||||||
"Trash Can File Versioning": "Verzování souborů v koši",
|
"Trash Can File Versioning": "Verzování souborů v koši",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Verze",
|
"Version": "Verze",
|
||||||
"Versions Path": "Cesta k verzím",
|
"Versions Path": "Cesta k verzím",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Verze jsou automaticky smazány, pokud jsou starší než maximální časový limit nebo překročí počet souborů povolených pro interval.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Verze jsou automaticky smazány, pokud jsou starší než maximální časový limit nebo překročí počet souborů povolených pro interval.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Při přidávání nového přístroje mějte na paměti, že je ho třeba také zadat na druhé straně.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Při přidávání nového přístroje mějte na paměti, že je ho třeba také zadat na druhé straně.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Při přidávání nového adresáře mějte na paměti, že jeho ID je použito ke svázání adresářů napříč přístoji. Rozlišují se malá a velká písmena a musí přesně souhlasit mezi všemi přístroji.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Při přidávání nového adresáře mějte na paměti, že jeho ID je použito ke svázání adresářů napříč přístoji. Rozlišují se malá a velká písmena a musí přesně souhlasit mezi všemi přístroji.",
|
||||||
"Yes": "Ano",
|
"Yes": "Ano",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "dní",
|
"days": "dní",
|
||||||
"full documentation": "plná dokumentace",
|
"full documentation": "plná dokumentace",
|
||||||
"items": "položky",
|
"items": "položky",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} chce sdílet adresář \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} chce sdílet adresář \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Tilføj",
|
"Add": "Tilføj",
|
||||||
"Add Device": "Tilføj enhed",
|
"Add Device": "Tilføj enhed",
|
||||||
"Add Folder": "Tilføj mappe",
|
"Add Folder": "Tilføj mappe",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Tilføj ny mappe",
|
"Add new folder?": "Tilføj ny mappe",
|
||||||
"Address": "Adresse",
|
"Address": "Adresse",
|
||||||
"Addresses": "Adresser",
|
"Addresses": "Adresser",
|
||||||
"Advanced": "Avanceret",
|
"Advanced": "Avanceret",
|
||||||
"Advanced Configuration": "Avanceret konfiguration",
|
"Advanced Configuration": "Avanceret konfiguration",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Alt data",
|
"All Data": "Alt data",
|
||||||
"Allow Anonymous Usage Reporting?": "Tillad anonym brugerstatistik?",
|
"Allow Anonymous Usage Reporting?": "Tillad anonym brugerstatistik?",
|
||||||
"Alphabetic": "Alfabetisk",
|
"Alphabetic": "Alfabetisk",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Tilslutnings fejl",
|
"Connection Error": "Tilslutnings fejl",
|
||||||
"Copied from elsewhere": "Kopieret fra et andet sted",
|
"Copied from elsewhere": "Kopieret fra et andet sted",
|
||||||
"Copied from original": "Kopieret fra originalen",
|
"Copied from original": "Kopieret fra originalen",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 alle bidragsydere:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 alle bidragsydere:",
|
||||||
"Danger!": "Fare!",
|
"Danger!": "Fare!",
|
||||||
"Delete": "Slet",
|
"Delete": "Slet",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Filer er beskyttet fra ændringer foretaget på andre enheder, men ændringerne på denne enhed vil blive sendt til alle andre tilknyttede enheder.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Filer er beskyttet fra ændringer foretaget på andre enheder, men ændringerne på denne enhed vil blive sendt til alle andre tilknyttede enheder.",
|
||||||
"Folder": "Mappe",
|
"Folder": "Mappe",
|
||||||
"Folder ID": "Mappe-ID",
|
"Folder ID": "Mappe-ID",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Mastermappe",
|
"Folder Master": "Mastermappe",
|
||||||
"Folder Path": "Mappesti",
|
"Folder Path": "Mappesti",
|
||||||
"Folders": "Mapper",
|
"Folders": "Mapper",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Slå fra",
|
"Off": "Slå fra",
|
||||||
"Oldest First": "Ældste først",
|
"Oldest First": "Ældste først",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Indstillinger",
|
"Options": "Indstillinger",
|
||||||
"Out of Sync": "Ikke synkroniseret",
|
"Out of Sync": "Ikke synkroniseret",
|
||||||
"Out of Sync Items": "Endnu ikke synkroniserede filer",
|
"Out of Sync Items": "Endnu ikke synkroniserede filer",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Passeret gennem",
|
"Relayed via": "Passeret gennem",
|
||||||
"Relays": "Passager",
|
"Relays": "Passager",
|
||||||
"Release Notes": "Udgivelsesnoter",
|
"Release Notes": "Udgivelsesnoter",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Fjern",
|
"Remove": "Fjern",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Skan igen",
|
"Rescan": "Skan igen",
|
||||||
"Rescan All": "Skan alt igen",
|
"Rescan All": "Skan alt igen",
|
||||||
"Rescan Interval": "Genskannings interval",
|
"Rescan Interval": "Genskannings interval",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "Ratebegrænsningen må ikke være negative tal (0: ingen begrænsning)",
|
"The rate limit must be a non-negative number (0: no limit)": "Ratebegrænsningen må ikke være negative tal (0: ingen begrænsning)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Genskanningsintervallet skal være et ikke-negativt antal sekunder",
|
"The rescan interval must be a non-negative number of seconds.": "Genskanningsintervallet skal være et ikke-negativt antal sekunder",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "De prøves igen automatisk og vil blive synkroniseret når fejlen er løst.",
|
"They are retried automatically and will be synced when the error is resolved.": "De prøves igen automatisk og vil blive synkroniseret når fejlen er løst.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Dette gør det nemt for hackere at få adgang til at læse og ændre filer på din computer.",
|
"This can easily give hackers access to read and change any files on your computer.": "Dette gør det nemt for hackere at få adgang til at læse og ændre filer på din computer.",
|
||||||
"This is a major version upgrade.": "Dette er en ny version",
|
"This is a major version upgrade.": "Dette er en ny version",
|
||||||
"Trash Can File Versioning": "Skraldespand fil versioner",
|
"Trash Can File Versioning": "Skraldespand fil versioner",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Version",
|
"Version": "Version",
|
||||||
"Versions Path": "Versions-sti",
|
"Versions Path": "Versions-sti",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versioner slettes automatisk, hvis de er ældre end den satte maksimum alder eller overstiger det tilladte antal filer i et interval.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versioner slettes automatisk, hvis de er ældre end den satte maksimum alder eller overstiger det tilladte antal filer i et interval.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Når der tilføjes en ny enhed, vær da opmærksom på, at denne enhed også skal tilføjes på den anden side.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Når der tilføjes en ny enhed, vær da opmærksom på, at denne enhed også skal tilføjes på den anden side.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Når der tilføjes en ny enhed, vær da opmærksom på at samme ID bruges til at forbinde mapperne på de forskellige enheder. Der er forskel på store og små bogstaver, og ID skal være fuldstændig identisk på alle enheder.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Når der tilføjes en ny enhed, vær da opmærksom på at samme ID bruges til at forbinde mapperne på de forskellige enheder. Der er forskel på store og små bogstaver, og ID skal være fuldstændig identisk på alle enheder.",
|
||||||
"Yes": "Ja",
|
"Yes": "Ja",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "dage",
|
"days": "dage",
|
||||||
"full documentation": "Fuld dokumentation",
|
"full documentation": "Fuld dokumentation",
|
||||||
"items": "poster",
|
"items": "poster",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} ønsker at dele mappen \"{{folder}}\". "
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} ønsker at dele mappen \"{{folder}}\". ",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Hinzufügen",
|
"Add": "Hinzufügen",
|
||||||
"Add Device": "Gerät hinzufügen",
|
"Add Device": "Gerät hinzufügen",
|
||||||
"Add Folder": "Verzeichnis hinzufügen",
|
"Add Folder": "Verzeichnis hinzufügen",
|
||||||
|
"Add Remote Device": "Remote-Gerät hinzufügen",
|
||||||
"Add new folder?": "Neues Verzeichnis hinzufügen?",
|
"Add new folder?": "Neues Verzeichnis hinzufügen?",
|
||||||
"Address": "Adresse",
|
"Address": "Adresse",
|
||||||
"Addresses": "Adressen",
|
"Addresses": "Adressen",
|
||||||
"Advanced": "Erweitert",
|
"Advanced": "Erweitert",
|
||||||
"Advanced Configuration": "Erweiterte Konfiguration",
|
"Advanced Configuration": "Erweiterte Konfiguration",
|
||||||
|
"Advanced settings": "Erweiterte Einstellungen",
|
||||||
"All Data": "Alle Daten",
|
"All Data": "Alle Daten",
|
||||||
"Allow Anonymous Usage Reporting?": "Übertragung von anonymen Nutzungsberichten erlauben?",
|
"Allow Anonymous Usage Reporting?": "Übertragung von anonymen Nutzungsberichten erlauben?",
|
||||||
"Alphabetic": "Alphabetisch",
|
"Alphabetic": "Alphabetisch",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Verbindungsfehler",
|
"Connection Error": "Verbindungsfehler",
|
||||||
"Copied from elsewhere": "Von anderer Quelle kopiert",
|
"Copied from elsewhere": "Von anderer Quelle kopiert",
|
||||||
"Copied from original": "Vom Original kopiert",
|
"Copied from original": "Vom Original kopiert",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 die folgenden Unterstützer:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 die folgenden Unterstützer:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 die folgenden Unterstützer:",
|
||||||
"Danger!": "Achtung!",
|
"Danger!": "Achtung!",
|
||||||
"Delete": "Löschen",
|
"Delete": "Löschen",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Dateien sind auf diesem Gerät schreibgeschützt. Auf diesem Gerät durchgeführte Veränderungen werden aber auf den Rest des Verbunds übertragen.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Dateien sind auf diesem Gerät schreibgeschützt. Auf diesem Gerät durchgeführte Veränderungen werden aber auf den Rest des Verbunds übertragen.",
|
||||||
"Folder": "Verzeichnis",
|
"Folder": "Verzeichnis",
|
||||||
"Folder ID": "Verzeichnis ID",
|
"Folder ID": "Verzeichnis ID",
|
||||||
|
"Folder Label": "Verzeichnisbezeichnung",
|
||||||
"Folder Master": "Master Verzeichnis - schreibgeschützt",
|
"Folder Master": "Master Verzeichnis - schreibgeschützt",
|
||||||
"Folder Path": "Verzeichnispfad",
|
"Folder Path": "Verzeichnispfad",
|
||||||
"Folders": "Verzeichnisse",
|
"Folders": "Verzeichnisse",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Aus",
|
"Off": "Aus",
|
||||||
"Oldest First": "Älteste zuerst",
|
"Oldest First": "Älteste zuerst",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optionale beschreibende Bezeichnung des Verzeichnisses. Kann auf jeden Gerät unterschiedlich sein.",
|
||||||
"Options": "Optionen",
|
"Options": "Optionen",
|
||||||
"Out of Sync": "Nicht synchronisiert",
|
"Out of Sync": "Nicht synchronisiert",
|
||||||
"Out of Sync Items": "Nicht synchronisierte Objekte",
|
"Out of Sync Items": "Nicht synchronisierte Objekte",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Weitergeleitet über",
|
"Relayed via": "Weitergeleitet über",
|
||||||
"Relays": "Weiterleitungen",
|
"Relays": "Weiterleitungen",
|
||||||
"Release Notes": "Veröffentlichungsnotizen",
|
"Release Notes": "Veröffentlichungsnotizen",
|
||||||
|
"Remote Devices": "Remote-Geräte",
|
||||||
"Remove": "Entfernen",
|
"Remove": "Entfernen",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Erforderliche ID für das Verzeichnis. Muss auf allen Verbunds-Geräten gleich sein.",
|
||||||
"Rescan": "Neu scannen",
|
"Rescan": "Neu scannen",
|
||||||
"Rescan All": "Alle neu scannen",
|
"Rescan All": "Alle neu scannen",
|
||||||
"Rescan Interval": "Scanintervall",
|
"Rescan Interval": "Scanintervall",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "Das Daterate-Limit muss eine nicht negative Anzahl sein (0 = kein Limit).",
|
"The rate limit must be a non-negative number (0: no limit)": "Das Daterate-Limit muss eine nicht negative Anzahl sein (0 = kein Limit).",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Das Scanintervall muss eine nicht negative Anzahl (in Sekunden) sein.",
|
"The rescan interval must be a non-negative number of seconds.": "Das Scanintervall muss eine nicht negative Anzahl (in Sekunden) sein.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Sie werden automatisch heruntergeladen und werden synchronisiert, wenn der Fehler behoben wurde.",
|
"They are retried automatically and will be synced when the error is resolved.": "Sie werden automatisch heruntergeladen und werden synchronisiert, wenn der Fehler behoben wurde.",
|
||||||
|
"This Device": "Dieses Gerät",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Dies kann dazu führen, dass Unberechtigte relativ einfach auf Ihre Dateien zugreifen und diese ändern können.",
|
"This can easily give hackers access to read and change any files on your computer.": "Dies kann dazu führen, dass Unberechtigte relativ einfach auf Ihre Dateien zugreifen und diese ändern können.",
|
||||||
"This is a major version upgrade.": "Dies ist eine neue Hauptversion.",
|
"This is a major version upgrade.": "Dies ist eine neue Hauptversion.",
|
||||||
"Trash Can File Versioning": "Papierkorb Dateiversionierung",
|
"Trash Can File Versioning": "Papierkorb Dateiversionierung",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Version",
|
"Version": "Version",
|
||||||
"Versions Path": "Versionierungspfad",
|
"Versions Path": "Versionierungspfad",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Alte Dateiversionen werden automatisch gelöscht, wenn sie älter als das angegebene Höchstalter sind oder die angegebene Höchstzahl an Dateien erreicht ist.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Alte Dateiversionen werden automatisch gelöscht, wenn sie älter als das angegebene Höchstalter sind oder die angegebene Höchstzahl an Dateien erreicht ist.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warnung, dieser Pfad ist ein Unterverzeichnis des existierenden Verzeichnisses \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Beachte beim Hinzufügen eines neuen Gerätes, dass dieses Gerät auch auf den anderen Geräten hinzugefügt werden muss.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Beachte beim Hinzufügen eines neuen Gerätes, dass dieses Gerät auch auf den anderen Geräten hinzugefügt werden muss.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Beachte bitte beim Hinzufügen eines neuen Verzeichnisses, dass die Verzeichnis ID dazu verwendet wird, Verzeichnisse zwischen Geräten zu verbinden. Die ID muss also auf allen Geräten gleich sein, die Groß- und Kleinschreibung muss dabei beachtet werden.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Beachte bitte beim Hinzufügen eines neuen Verzeichnisses, dass die Verzeichnis ID dazu verwendet wird, Verzeichnisse zwischen Geräten zu verbinden. Die ID muss also auf allen Geräten gleich sein, die Groß- und Kleinschreibung muss dabei beachtet werden.",
|
||||||
"Yes": "Ja",
|
"Yes": "Ja",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "Tage",
|
"days": "Tage",
|
||||||
"full documentation": "Komplette Dokumentation",
|
"full documentation": "Komplette Dokumentation",
|
||||||
"items": "Objekte",
|
"items": "Objekte",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} möchte das Verzeichnis \"{{folder}}\" teilen."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} möchte das Verzeichnis \"{{folder}}\" teilen.",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} möchte das Verzeichnis \"{{folderLabel}}\" ({{folder}}) teilen."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Προσθήκη",
|
"Add": "Προσθήκη",
|
||||||
"Add Device": "Προσθήκη συσκευής",
|
"Add Device": "Προσθήκη συσκευής",
|
||||||
"Add Folder": "Προσθήκη φακέλου",
|
"Add Folder": "Προσθήκη φακέλου",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Προσθήκη νέου φακέλου;",
|
"Add new folder?": "Προσθήκη νέου φακέλου;",
|
||||||
"Address": "Διεύθυνση",
|
"Address": "Διεύθυνση",
|
||||||
"Addresses": "Διευθύνσεις",
|
"Addresses": "Διευθύνσεις",
|
||||||
"Advanced": "Προχωρημένες",
|
"Advanced": "Προχωρημένες",
|
||||||
"Advanced Configuration": "Προχωρημένες ρυθμίσεις",
|
"Advanced Configuration": "Προχωρημένες ρυθμίσεις",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Όλα τα δεδομένα",
|
"All Data": "Όλα τα δεδομένα",
|
||||||
"Allow Anonymous Usage Reporting?": "Να επιτρέπεται η αποστολή ανώνυμων στοιχείων χρήσης;",
|
"Allow Anonymous Usage Reporting?": "Να επιτρέπεται η αποστολή ανώνυμων στοιχείων χρήσης;",
|
||||||
"Alphabetic": "Αλφαβητικά",
|
"Alphabetic": "Αλφαβητικά",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Σφάλμα σύνδεσης",
|
"Connection Error": "Σφάλμα σύνδεσης",
|
||||||
"Copied from elsewhere": "Έχει αντιγραφεί από κάπου αλλού",
|
"Copied from elsewhere": "Έχει αντιγραφεί από κάπου αλλού",
|
||||||
"Copied from original": "Έχει αντιγραφεί από το πρωτότυπο",
|
"Copied from original": "Έχει αντιγραφεί από το πρωτότυπο",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 από τους παρακάτω συνεισφορείς:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 από τους παρακάτω συνεισφορείς:",
|
||||||
"Danger!": "Προσοχή!",
|
"Danger!": "Προσοχή!",
|
||||||
"Delete": "Διαγραφή",
|
"Delete": "Διαγραφή",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Τα αρχεία προστατεύονται από αλλαγές που γίνονται σε άλλες συσκευές, αλλά όποιες αλλαγές γίνουν σε αυτή τη συσκευή θα αποσταλούν σε όλη τη συστάδα συσκευών.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Τα αρχεία προστατεύονται από αλλαγές που γίνονται σε άλλες συσκευές, αλλά όποιες αλλαγές γίνουν σε αυτή τη συσκευή θα αποσταλούν σε όλη τη συστάδα συσκευών.",
|
||||||
"Folder": "Φάκελος",
|
"Folder": "Φάκελος",
|
||||||
"Folder ID": "Ταυτότητα φακέλου",
|
"Folder ID": "Ταυτότητα φακέλου",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Να μην επιτρέπονται αλλαγές",
|
"Folder Master": "Να μην επιτρέπονται αλλαγές",
|
||||||
"Folder Path": "Μονοπάτι φακέλου",
|
"Folder Path": "Μονοπάτι φακέλου",
|
||||||
"Folders": "Φάκελοι",
|
"Folders": "Φάκελοι",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Απενεργοποιημένο",
|
"Off": "Απενεργοποιημένο",
|
||||||
"Oldest First": "Το παλιότερο πρώτα",
|
"Oldest First": "Το παλιότερο πρώτα",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Επιλογές",
|
"Options": "Επιλογές",
|
||||||
"Out of Sync": "Μη συγχρονισμένα",
|
"Out of Sync": "Μη συγχρονισμένα",
|
||||||
"Out of Sync Items": "Μη συγχρονισμένα αντικείμενα",
|
"Out of Sync Items": "Μη συγχρονισμένα αντικείμενα",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Αναμετάδοση μέσω",
|
"Relayed via": "Αναμετάδοση μέσω",
|
||||||
"Relays": "Αναμεταδόσεις",
|
"Relays": "Αναμεταδόσεις",
|
||||||
"Release Notes": "Σημείωμα έκδοσης",
|
"Release Notes": "Σημείωμα έκδοσης",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Αφαίρεση",
|
"Remove": "Αφαίρεση",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Έλεγξε για αλλαγές",
|
"Rescan": "Έλεγξε για αλλαγές",
|
||||||
"Rescan All": "Έλεγξέ τα όλα για αλλαγές",
|
"Rescan All": "Έλεγξέ τα όλα για αλλαγές",
|
||||||
"Rescan Interval": "Κάθε πότε θα ελέγχεται για αλλαγές ",
|
"Rescan Interval": "Κάθε πότε θα ελέγχεται για αλλαγές ",
|
||||||
@@ -181,7 +188,7 @@
|
|||||||
"The aggregated statistics are publicly available at {%url%}.": "Τα στατιστικά που έχουν συλλεγεί είναι δημόσια διαθέσιμα στο {{url}}.",
|
"The aggregated statistics are publicly available at {%url%}.": "Τα στατιστικά που έχουν συλλεγεί είναι δημόσια διαθέσιμα στο {{url}}.",
|
||||||
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Οι ρυθμίσεις έχουν αποθηκευτεί αλλά δεν έχουν ενεργοποιηθεί. Πρέπει να επανεκκινήσεις το Syncthing για να ισχύσουν οι νέες ρυθμίσεις.",
|
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Οι ρυθμίσεις έχουν αποθηκευτεί αλλά δεν έχουν ενεργοποιηθεί. Πρέπει να επανεκκινήσεις το Syncthing για να ισχύσουν οι νέες ρυθμίσεις.",
|
||||||
"The device ID cannot be blank.": "Η ταυτότητα της συσκευής δεν μπορεί να είναι κενή",
|
"The device ID cannot be blank.": "Η ταυτότητα της συσκευής δεν μπορεί να είναι κενή",
|
||||||
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).",
|
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Η ταυτότητα της συσκευής που θα μπει εδώ βρίσκεται στο μενού «Ενέργειες > Εμφάνιση ταυτότητας» στην άλλη συσκευή. Κενοί χαρακτήρες και παύλες είναι προαιρετικοί (θα αγνοηθούν).",
|
||||||
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Η ταυτότητα της συσκευής που θα μπει εδώ βρίσκεται στο μενού «Επεξεργασία > Εμφάνιση ταυτότητας» στην άλλη συσκευή. Κενοί χαρακτήρες και παύλες είναι προαιρετικοί (απλά θα αγνοηθούν).",
|
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Η ταυτότητα της συσκευής που θα μπει εδώ βρίσκεται στο μενού «Επεξεργασία > Εμφάνιση ταυτότητας» στην άλλη συσκευή. Κενοί χαρακτήρες και παύλες είναι προαιρετικοί (απλά θα αγνοηθούν).",
|
||||||
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "Η κρυπτογραφημένη αναφορά χρήσης στέλνεται καθημερινά. Χρησιμοποιείται για να παραχθούν στατιστικές για τα λειτουργικά συστήματα που χρησιμοποιούνται, τα μεγέθη των φακέλων και τις εκδόσεις των προγραμμάτων. Αν στο μέλλον συμπεριληφθούν και άλλα δεδομένα στην αναφορά χρήσης, τότε αυτό το παράθυρο θα εμφανιστεί ξανά.",
|
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "Η κρυπτογραφημένη αναφορά χρήσης στέλνεται καθημερινά. Χρησιμοποιείται για να παραχθούν στατιστικές για τα λειτουργικά συστήματα που χρησιμοποιούνται, τα μεγέθη των φακέλων και τις εκδόσεις των προγραμμάτων. Αν στο μέλλον συμπεριληφθούν και άλλα δεδομένα στην αναφορά χρήσης, τότε αυτό το παράθυρο θα εμφανιστεί ξανά.",
|
||||||
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "Η ταυτότητα συσκευής που έδωσες δε φαίνεται έγκυρη. Θα πρέπει να είναι μια σειρά από 52 ή 56 χαρακτήρες (γράμματα και αριθμοί). Τα κενά και οι παύλες είναι προαιρετικά (αδιάφορα).",
|
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "Η ταυτότητα συσκευής που έδωσες δε φαίνεται έγκυρη. Θα πρέπει να είναι μια σειρά από 52 ή 56 χαρακτήρες (γράμματα και αριθμοί). Τα κενά και οι παύλες είναι προαιρετικά (αδιάφορα).",
|
||||||
@@ -194,16 +201,17 @@
|
|||||||
"The following items could not be synchronized.": "Δεν ήταν δυνατόν να συγχρονιστούν τα παρακάτω αρχεία.",
|
"The following items could not be synchronized.": "Δεν ήταν δυνατόν να συγχρονιστούν τα παρακάτω αρχεία.",
|
||||||
"The maximum age must be a number and cannot be blank.": "Η μέγιστη ηλικία πρέπει να είναι αριθμός και σίγουρα όχι κενό.",
|
"The maximum age must be a number and cannot be blank.": "Η μέγιστη ηλικία πρέπει να είναι αριθμός και σίγουρα όχι κενό.",
|
||||||
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Η μέγιστη ηλικία παλιότερων εκδόσεων (σε ημέρες, αν δώσεις 0 οι παλιότερες εκδόσεις θα διατηρούνται για πάντα).",
|
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Η μέγιστη ηλικία παλιότερων εκδόσεων (σε ημέρες, αν δώσεις 0 οι παλιότερες εκδόσεις θα διατηρούνται για πάντα).",
|
||||||
"The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).": "The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).",
|
"The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).": "Το ποσοστό του ελάχιστου διαθέσιμου αποθηκευτικόυ χώρου πρέπει να είναι έναν μη-αρνητικός αριθμός μεταξύ του 0 και του 100 (συμπεριλαμβανομένων)",
|
||||||
"The number of days must be a number and cannot be blank.": "Ο αριθμός ημερών πρέπει να είναι αριθμός και σίγουρα όχι κενό.",
|
"The number of days must be a number and cannot be blank.": "Ο αριθμός ημερών πρέπει να είναι αριθμός και σίγουρα όχι κενό.",
|
||||||
"The number of days to keep files in the trash can. Zero means forever.": "Ο αριθμός ημερών που θα διατηρούντα τα αρχεία στον κάδο. Μηδέν σημαίνει διατήρηση για πάντα.",
|
"The number of days to keep files in the trash can. Zero means forever.": "Ο αριθμός ημερών που θα διατηρούντα τα αρχεία στον κάδο. Μηδέν σημαίνει διατήρηση για πάντα.",
|
||||||
"The number of old versions to keep, per file.": "Πόσες παλιότερες εκδόσεις θα διατηρούνται, ανά αρχείο.",
|
"The number of old versions to keep, per file.": "Πόσες παλιότερες εκδόσεις θα διατηρούνται, ανά αρχείο.",
|
||||||
"The number of versions must be a number and cannot be blank.": "Ο αριθμός εκδόσεων πρέπει να είναι αριθμός και σίγουρα όχι κενό.",
|
"The number of versions must be a number and cannot be blank.": "Ο αριθμός εκδόσεων πρέπει να είναι αριθμός και σίγουρα όχι κενό.",
|
||||||
"The path cannot be blank.": "Το μονοπάτι δεν μπορεί να είναι κενό.",
|
"The path cannot be blank.": "Το μονοπάτι δεν μπορεί να είναι κενό.",
|
||||||
"The rate limit must be a non-negative number (0: no limit)": "The rate limit must be a non-negative number (0: no limit)",
|
"The rate limit must be a non-negative number (0: no limit)": "Το όριο ταχύτητας πρέπει να είναι ένας μη-αρνητικός αριθμός (0: χωρίς όριο)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Ο χρόνος επανελέγχου για αλλαγές είναι σε δευτερόλεπτα (δηλ. θετικός αριθμός).",
|
"The rescan interval must be a non-negative number of seconds.": "Ο χρόνος επανελέγχου για αλλαγές είναι σε δευτερόλεπτα (δηλ. θετικός αριθμός).",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Όταν επιλυθεί το σφάλμα θα κατεβούν και θα συχρονιστούν αυτόματα.",
|
"They are retried automatically and will be synced when the error is resolved.": "Όταν επιλυθεί το σφάλμα θα κατεβούν και θα συχρονιστούν αυτόματα.",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
"This Device": "This Device",
|
||||||
|
"This can easily give hackers access to read and change any files on your computer.": "Αυτό μπορεί εύκολα να δώσει πρόσβαση ανάγνωσης και επεξεργασίας αρχείων του υπολογιστή σας σε χάκερς.",
|
||||||
"This is a major version upgrade.": "Αυτή είναι μιας σημαντική αναβάθμιση.",
|
"This is a major version upgrade.": "Αυτή είναι μιας σημαντική αναβάθμιση.",
|
||||||
"Trash Can File Versioning": "Ο κάδος μπορεί να τηρεί εκδόσεις",
|
"Trash Can File Versioning": "Ο κάδος μπορεί να τηρεί εκδόσεις",
|
||||||
"Unknown": "Άγνωστο",
|
"Unknown": "Άγνωστο",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Έκδοση",
|
"Version": "Έκδοση",
|
||||||
"Versions Path": "Φάκελος τήρησης εκδόσεων",
|
"Versions Path": "Φάκελος τήρησης εκδόσεων",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Οι παλιές εκδόσεις θα σβήνονται αυτόματα όταν ξεπεράσουν τη μέγιστη ηλικία ή όταν ξεπεραστεί ο μέγιστος αριθμός αρχείων ανά περίοδο.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Οι παλιές εκδόσεις θα σβήνονται αυτόματα όταν ξεπεράσουν τη μέγιστη ηλικία ή όταν ξεπεραστεί ο μέγιστος αριθμός αρχείων ανά περίοδο.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Θυμήσου πως όταν προσθέτεις μια νέα συσκευή, ετούτη η συσκευή θα πρέπει να προστεθεί και στην άλλη πλευρά.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Θυμήσου πως όταν προσθέτεις μια νέα συσκευή, ετούτη η συσκευή θα πρέπει να προστεθεί και στην άλλη πλευρά.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Όταν προσθέτεις έναν νέο φάκελο, θυμήσου πως η ταυτότητα ενός φακέλου χρησιμοποιείται για να να συσχετίσει φακέλους μεταξύ συσκευών. Η ταυτότητα του φακέλου θα πρέπει να είναι η ίδια σε όλες τις συσκευές και έχουν σημασία τα πεζά ή κεφαλαία γράμματα.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Όταν προσθέτεις έναν νέο φάκελο, θυμήσου πως η ταυτότητα ενός φακέλου χρησιμοποιείται για να να συσχετίσει φακέλους μεταξύ συσκευών. Η ταυτότητα του φακέλου θα πρέπει να είναι η ίδια σε όλες τις συσκευές και έχουν σημασία τα πεζά ή κεφαλαία γράμματα.",
|
||||||
"Yes": "Ναι",
|
"Yes": "Ναι",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "Μέρες",
|
"days": "Μέρες",
|
||||||
"full documentation": "πλήρης τεκμηρίωση",
|
"full documentation": "πλήρης τεκμηρίωση",
|
||||||
"items": "εγγραφές",
|
"items": "εγγραφές",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "Η συσκευή {{device}} θέλει να μοιράσει τον φάκελο «{{folder}}»."
|
"{%device%} wants to share folder \"{%folder%}\".": "Η συσκευή {{device}} θέλει να μοιράσει τον φάκελο «{{folder}}».",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Add",
|
"Add": "Add",
|
||||||
"Add Device": "Add Device",
|
"Add Device": "Add Device",
|
||||||
"Add Folder": "Add Folder",
|
"Add Folder": "Add Folder",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Add new folder?",
|
"Add new folder?": "Add new folder?",
|
||||||
"Address": "Address",
|
"Address": "Address",
|
||||||
"Addresses": "Addresses",
|
"Addresses": "Addresses",
|
||||||
"Advanced": "Advanced",
|
"Advanced": "Advanced",
|
||||||
"Advanced Configuration": "Advanced Configuration",
|
"Advanced Configuration": "Advanced Configuration",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "All Data",
|
"All Data": "All Data",
|
||||||
"Allow Anonymous Usage Reporting?": "Allow Anonymous Usage Reporting?",
|
"Allow Anonymous Usage Reporting?": "Allow Anonymous Usage Reporting?",
|
||||||
"Alphabetic": "Alphabetic",
|
"Alphabetic": "Alphabetic",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Connection Error",
|
"Connection Error": "Connection Error",
|
||||||
"Copied from elsewhere": "Copied from elsewhere",
|
"Copied from elsewhere": "Copied from elsewhere",
|
||||||
"Copied from original": "Copied from original",
|
"Copied from original": "Copied from original",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
|
||||||
"Danger!": "Danger!",
|
"Danger!": "Danger!",
|
||||||
"Delete": "Delete",
|
"Delete": "Delete",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.",
|
||||||
"Folder": "Folder",
|
"Folder": "Folder",
|
||||||
"Folder ID": "Folder ID",
|
"Folder ID": "Folder ID",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Folder Master",
|
"Folder Master": "Folder Master",
|
||||||
"Folder Path": "Folder Path",
|
"Folder Path": "Folder Path",
|
||||||
"Folders": "Folders",
|
"Folders": "Folders",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Off",
|
"Off": "Off",
|
||||||
"Oldest First": "Oldest First",
|
"Oldest First": "Oldest First",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Options",
|
"Options": "Options",
|
||||||
"Out of Sync": "Out of Sync",
|
"Out of Sync": "Out of Sync",
|
||||||
"Out of Sync Items": "Out of Sync Items",
|
"Out of Sync Items": "Out of Sync Items",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Relayed via",
|
"Relayed via": "Relayed via",
|
||||||
"Relays": "Relays",
|
"Relays": "Relays",
|
||||||
"Release Notes": "Release Notes",
|
"Release Notes": "Release Notes",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Remove",
|
"Remove": "Remove",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Rescan",
|
"Rescan": "Rescan",
|
||||||
"Rescan All": "Rescan All",
|
"Rescan All": "Rescan All",
|
||||||
"Rescan Interval": "Rescan Interval",
|
"Rescan Interval": "Rescan Interval",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "The rate limit must be a non-negative number (0: no limit)",
|
"The rate limit must be a non-negative number (0: no limit)": "The rate limit must be a non-negative number (0: no limit)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "The rescan interval must be a non-negative number of seconds.",
|
"The rescan interval must be a non-negative number of seconds.": "The rescan interval must be a non-negative number of seconds.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "They are retried automatically and will be synced when the error is resolved.",
|
"They are retried automatically and will be synced when the error is resolved.": "They are retried automatically and will be synced when the error is resolved.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
||||||
"This is a major version upgrade.": "This is a major version upgrade.",
|
"This is a major version upgrade.": "This is a major version upgrade.",
|
||||||
"Trash Can File Versioning": "Rubbish Bin File Versioning",
|
"Trash Can File Versioning": "Rubbish Bin File Versioning",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Version",
|
"Version": "Version",
|
||||||
"Versions Path": "Versions Path",
|
"Versions Path": "Versions Path",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "When adding a new device, keep in mind that this device must be added on the other side too.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "When adding a new device, keep in mind that this device must be added on the other side too.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.",
|
||||||
"Yes": "Yes",
|
"Yes": "Yes",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "days",
|
"days": "days",
|
||||||
"full documentation": "full documentation",
|
"full documentation": "full documentation",
|
||||||
"items": "items",
|
"items": "items",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} wants to share folder \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} wants to share folder \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Add",
|
"Add": "Add",
|
||||||
"Add Device": "Add Device",
|
"Add Device": "Add Device",
|
||||||
"Add Folder": "Add Folder",
|
"Add Folder": "Add Folder",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Add new folder?",
|
"Add new folder?": "Add new folder?",
|
||||||
"Address": "Address",
|
"Address": "Address",
|
||||||
"Addresses": "Addresses",
|
"Addresses": "Addresses",
|
||||||
"Advanced": "Advanced",
|
"Advanced": "Advanced",
|
||||||
"Advanced Configuration": "Advanced Configuration",
|
"Advanced Configuration": "Advanced Configuration",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "All Data",
|
"All Data": "All Data",
|
||||||
"Allow Anonymous Usage Reporting?": "Allow Anonymous Usage Reporting?",
|
"Allow Anonymous Usage Reporting?": "Allow Anonymous Usage Reporting?",
|
||||||
"Alphabetic": "Alphabetic",
|
"Alphabetic": "Alphabetic",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Connection Error",
|
"Connection Error": "Connection Error",
|
||||||
"Copied from elsewhere": "Copied from elsewhere",
|
"Copied from elsewhere": "Copied from elsewhere",
|
||||||
"Copied from original": "Copied from original",
|
"Copied from original": "Copied from original",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
|
||||||
"Danger!": "Danger!",
|
"Danger!": "Danger!",
|
||||||
"Delete": "Delete",
|
"Delete": "Delete",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.",
|
||||||
"Folder": "Folder",
|
"Folder": "Folder",
|
||||||
"Folder ID": "Folder ID",
|
"Folder ID": "Folder ID",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Folder Master",
|
"Folder Master": "Folder Master",
|
||||||
"Folder Path": "Folder Path",
|
"Folder Path": "Folder Path",
|
||||||
"Folders": "Folders",
|
"Folders": "Folders",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Off",
|
"Off": "Off",
|
||||||
"Oldest First": "Oldest First",
|
"Oldest First": "Oldest First",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Options",
|
"Options": "Options",
|
||||||
"Out of Sync": "Out of Sync",
|
"Out of Sync": "Out of Sync",
|
||||||
"Out of Sync Items": "Out of Sync Items",
|
"Out of Sync Items": "Out of Sync Items",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Relayed via",
|
"Relayed via": "Relayed via",
|
||||||
"Relays": "Relays",
|
"Relays": "Relays",
|
||||||
"Release Notes": "Release Notes",
|
"Release Notes": "Release Notes",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Remove",
|
"Remove": "Remove",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Rescan",
|
"Rescan": "Rescan",
|
||||||
"Rescan All": "Rescan All",
|
"Rescan All": "Rescan All",
|
||||||
"Rescan Interval": "Rescan Interval",
|
"Rescan Interval": "Rescan Interval",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "The rate limit must be a non-negative number (0: no limit)",
|
"The rate limit must be a non-negative number (0: no limit)": "The rate limit must be a non-negative number (0: no limit)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "The rescan interval must be a non-negative number of seconds.",
|
"The rescan interval must be a non-negative number of seconds.": "The rescan interval must be a non-negative number of seconds.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "They are retried automatically and will be synced when the error is resolved.",
|
"They are retried automatically and will be synced when the error is resolved.": "They are retried automatically and will be synced when the error is resolved.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
||||||
"This is a major version upgrade.": "This is a major version upgrade.",
|
"This is a major version upgrade.": "This is a major version upgrade.",
|
||||||
"Trash Can File Versioning": "Trash Can File Versioning",
|
"Trash Can File Versioning": "Trash Can File Versioning",
|
||||||
@@ -227,5 +235,6 @@
|
|||||||
"days": "days",
|
"days": "days",
|
||||||
"full documentation": "full documentation",
|
"full documentation": "full documentation",
|
||||||
"items": "items",
|
"items": "items",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} wants to share folder \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} wants to share folder \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Agregar",
|
"Add": "Agregar",
|
||||||
"Add Device": "Agregar Dispositivo",
|
"Add Device": "Agregar Dispositivo",
|
||||||
"Add Folder": "Agregar Carpeta",
|
"Add Folder": "Agregar Carpeta",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "¿Agregar una carpeta nueva?",
|
"Add new folder?": "¿Agregar una carpeta nueva?",
|
||||||
"Address": "Dirección",
|
"Address": "Dirección",
|
||||||
"Addresses": "Direcciones",
|
"Addresses": "Direcciones",
|
||||||
"Advanced": "Avanzado",
|
"Advanced": "Avanzado",
|
||||||
"Advanced Configuration": "Configuración Avanzada",
|
"Advanced Configuration": "Configuración Avanzada",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Todos los datos",
|
"All Data": "Todos los datos",
|
||||||
"Allow Anonymous Usage Reporting?": "¿Deseas permitir el envío anónimo de informes de uso?",
|
"Allow Anonymous Usage Reporting?": "¿Deseas permitir el envío anónimo de informes de uso?",
|
||||||
"Alphabetic": "Alfabético",
|
"Alphabetic": "Alfabético",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Error de conexión",
|
"Connection Error": "Error de conexión",
|
||||||
"Copied from elsewhere": "Copiado de otro sitio",
|
"Copied from elsewhere": "Copiado de otro sitio",
|
||||||
"Copied from original": "Copiado del original",
|
"Copied from original": "Copiado del original",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 los siguientes Colaboradores:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 los siguientes Colaboradores:",
|
||||||
"Danger!": "¡Peligro!",
|
"Danger!": "¡Peligro!",
|
||||||
"Delete": "Eliminar",
|
"Delete": "Eliminar",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Los ficheros son protegidos por los cambios hechos en otros dispositivos, pero los cambios hechos en este dispositivo serán enviados al resto del grupo (cluster).",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Los ficheros son protegidos por los cambios hechos en otros dispositivos, pero los cambios hechos en este dispositivo serán enviados al resto del grupo (cluster).",
|
||||||
"Folder": "Carpeta",
|
"Folder": "Carpeta",
|
||||||
"Folder ID": "ID de carpeta",
|
"Folder ID": "ID de carpeta",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Carpeta principal",
|
"Folder Master": "Carpeta principal",
|
||||||
"Folder Path": "Ruta de la carpeta",
|
"Folder Path": "Ruta de la carpeta",
|
||||||
"Folders": "Carpetas",
|
"Folders": "Carpetas",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Desconectar",
|
"Off": "Desconectar",
|
||||||
"Oldest First": "El más antiguo primero",
|
"Oldest First": "El más antiguo primero",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Opciones",
|
"Options": "Opciones",
|
||||||
"Out of Sync": "No sincronizado",
|
"Out of Sync": "No sincronizado",
|
||||||
"Out of Sync Items": "Elementos no sincronizados",
|
"Out of Sync Items": "Elementos no sincronizados",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Respaldada a través",
|
"Relayed via": "Respaldada a través",
|
||||||
"Relays": "Respaldos",
|
"Relays": "Respaldos",
|
||||||
"Release Notes": "Notas de la versión",
|
"Release Notes": "Notas de la versión",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Eliminar",
|
"Remove": "Eliminar",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Volver a analizar",
|
"Rescan": "Volver a analizar",
|
||||||
"Rescan All": "Volver a analizar Todo",
|
"Rescan All": "Volver a analizar Todo",
|
||||||
"Rescan Interval": "Intervalo de análisis",
|
"Rescan Interval": "Intervalo de análisis",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "El límite de velocidad debe ser un número no negativo (0: sin límite)",
|
"The rate limit must be a non-negative number (0: no limit)": "El límite de velocidad debe ser un número no negativo (0: sin límite)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "El intervalo de actualización debe ser un número positivo de segundos.",
|
"The rescan interval must be a non-negative number of seconds.": "El intervalo de actualización debe ser un número positivo de segundos.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Se reintentarán de forma automática y se sincronizarán cuando se resuelva el error.",
|
"They are retried automatically and will be synced when the error is resolved.": "Se reintentarán de forma automática y se sincronizarán cuando se resuelva el error.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Esto podría permitir fácilmente el acceso a hackers para leer y modificar cualquier fichero de tu equipo.",
|
"This can easily give hackers access to read and change any files on your computer.": "Esto podría permitir fácilmente el acceso a hackers para leer y modificar cualquier fichero de tu equipo.",
|
||||||
"This is a major version upgrade.": "Hay una actualización importante.",
|
"This is a major version upgrade.": "Hay una actualización importante.",
|
||||||
"Trash Can File Versioning": "Versionado de archivos de la papelera",
|
"Trash Can File Versioning": "Versionado de archivos de la papelera",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Versión",
|
"Version": "Versión",
|
||||||
"Versions Path": "Ruta de las versiones",
|
"Versions Path": "Ruta de las versiones",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Las versiones se borran automáticamente si son más antiguas que la edad máxima o exceden el número de ficheros permitidos en un intervalo.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Las versiones se borran automáticamente si son más antiguas que la edad máxima o exceden el número de ficheros permitidos en un intervalo.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Cuando añada un nuevo dispositivo, tenga en cuenta que este debe añadirse también en el otro lado.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Cuando añada un nuevo dispositivo, tenga en cuenta que este debe añadirse también en el otro lado.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Cuando añada una nueva carpeta, tenga en cuenta que su ID se usa para unir carpetas entre dispositivos. Son sensibles a las mayúsculas y deben coincidir exactamente entre todos los dispositivos.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Cuando añada una nueva carpeta, tenga en cuenta que su ID se usa para unir carpetas entre dispositivos. Son sensibles a las mayúsculas y deben coincidir exactamente entre todos los dispositivos.",
|
||||||
"Yes": "Si",
|
"Yes": "Si",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "días",
|
"days": "días",
|
||||||
"full documentation": "Documentación completa",
|
"full documentation": "Documentación completa",
|
||||||
"items": "Elementos",
|
"items": "Elementos",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} quiere compartir la carpeta \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} quiere compartir la carpeta \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"A device with that ID is already added.": "A device with that ID is already added.",
|
"A device with that ID is already added.": "Un dispositivo con esta ID ya está añadido.",
|
||||||
"A negative number of days doesn't make sense.": "Un número negativo no tiene sentido",
|
"A negative number of days doesn't make sense.": "Un número negativo no tiene sentido",
|
||||||
"A new major version may not be compatible with previous versions.": "Una versión mayor nueva puede ser incompatible con versiones anteriores.",
|
"A new major version may not be compatible with previous versions.": "Una versión mayor nueva puede ser incompatible con versiones anteriores.",
|
||||||
"API Key": "Clave API",
|
"API Key": "Clave API",
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Agregar",
|
"Add": "Agregar",
|
||||||
"Add Device": "Agregar Dispositivo",
|
"Add Device": "Agregar Dispositivo",
|
||||||
"Add Folder": "Agregar Repositorio",
|
"Add Folder": "Agregar Repositorio",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "¿Agregar nueva carpeta?",
|
"Add new folder?": "¿Agregar nueva carpeta?",
|
||||||
"Address": "Dirección",
|
"Address": "Dirección",
|
||||||
"Addresses": "Direcciones",
|
"Addresses": "Direcciones",
|
||||||
"Advanced": "Avanzada",
|
"Advanced": "Avanzada",
|
||||||
"Advanced Configuration": "Configuración avanzada",
|
"Advanced Configuration": "Configuración avanzada",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Todos los datos",
|
"All Data": "Todos los datos",
|
||||||
"Allow Anonymous Usage Reporting?": "Permitir reporte anónimo de uso?",
|
"Allow Anonymous Usage Reporting?": "Permitir reporte anónimo de uso?",
|
||||||
"Alphabetic": "Alfabético",
|
"Alphabetic": "Alfabético",
|
||||||
@@ -32,8 +34,9 @@
|
|||||||
"Connection Error": "Error de conexión",
|
"Connection Error": "Error de conexión",
|
||||||
"Copied from elsewhere": "Copiado desde otra parte.",
|
"Copied from elsewhere": "Copiado desde otra parte.",
|
||||||
"Copied from original": "Copiado del original",
|
"Copied from original": "Copiado del original",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Derechos de autor © 2015 los siguientes colaboradores:",
|
"Copyright © 2015 the following Contributors:": "Derechos de autor © 2015 los siguientes colaboradores:",
|
||||||
"Danger!": "Danger!",
|
"Danger!": "Peligro!",
|
||||||
"Delete": "Suprimir",
|
"Delete": "Suprimir",
|
||||||
"Deleted": "Suprimido",
|
"Deleted": "Suprimido",
|
||||||
"Device ID": "ID del dispositivo",
|
"Device ID": "ID del dispositivo",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Los archivos están protegidos frente a los cambios realizados en otros dispositivos, peros los cambios realizados en este dispositivo serán envíados al resto del grupo",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Los archivos están protegidos frente a los cambios realizados en otros dispositivos, peros los cambios realizados en este dispositivo serán envíados al resto del grupo",
|
||||||
"Folder": "Carpeta",
|
"Folder": "Carpeta",
|
||||||
"Folder ID": "ID del repositorio",
|
"Folder ID": "ID del repositorio",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Repositorio maestro",
|
"Folder Master": "Repositorio maestro",
|
||||||
"Folder Path": "Ruta del repositorio",
|
"Folder Path": "Ruta del repositorio",
|
||||||
"Folders": "Repositorios",
|
"Folders": "Repositorios",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Apagado",
|
"Off": "Apagado",
|
||||||
"Oldest First": "Antiguo primero",
|
"Oldest First": "Antiguo primero",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Opciones",
|
"Options": "Opciones",
|
||||||
"Out of Sync": "Fuera de sincronización",
|
"Out of Sync": "Fuera de sincronización",
|
||||||
"Out of Sync Items": "Ítems no sincronizados",
|
"Out of Sync Items": "Ítems no sincronizados",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "retransmitida vía",
|
"Relayed via": "retransmitida vía",
|
||||||
"Relays": "Retransmisores",
|
"Relays": "Retransmisores",
|
||||||
"Release Notes": "Notas de lanzamiento",
|
"Release Notes": "Notas de lanzamiento",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Eliminar",
|
"Remove": "Eliminar",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Reescanear",
|
"Rescan": "Reescanear",
|
||||||
"Rescan All": "Reescanear todo",
|
"Rescan All": "Reescanear todo",
|
||||||
"Rescan Interval": "Intervalo de reescaneo",
|
"Rescan Interval": "Intervalo de reescaneo",
|
||||||
@@ -155,7 +162,7 @@
|
|||||||
"Shared With": "Compartido con",
|
"Shared With": "Compartido con",
|
||||||
"Short identifier for the folder. Must be the same on all cluster devices.": "Identificador corto para el repositorio. Debe ser el mismo en todos los dispositivos del grupo.",
|
"Short identifier for the folder. Must be the same on all cluster devices.": "Identificador corto para el repositorio. Debe ser el mismo en todos los dispositivos del grupo.",
|
||||||
"Show ID": "Mostrar ID",
|
"Show ID": "Mostrar ID",
|
||||||
"Show QR": "Show QR",
|
"Show QR": "Mostrar QR",
|
||||||
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Mostrado en lugar de la ID del dispositivo en el estado del grupo. Será sugerido a otros dispositivos como nombre predeterminado opcional.",
|
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Mostrado en lugar de la ID del dispositivo en el estado del grupo. Será sugerido a otros dispositivos como nombre predeterminado opcional.",
|
||||||
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Mostrado en lugar de la ID del dispositivo en el estado del grupo. Si se deja en blanco, será usado el nombre sugerido por el dispositivo.",
|
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Mostrado en lugar de la ID del dispositivo en el estado del grupo. Si se deja en blanco, será usado el nombre sugerido por el dispositivo.",
|
||||||
"Shutdown": "Apagar",
|
"Shutdown": "Apagar",
|
||||||
@@ -177,7 +184,7 @@
|
|||||||
"Syncthing is upgrading.": "Syncthing se está actualizando.",
|
"Syncthing is upgrading.": "Syncthing se está actualizando.",
|
||||||
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing parece estar apagado, o hay un problema con su conexión de Internet. Reintentando...",
|
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing parece estar apagado, o hay un problema con su conexión de Internet. Reintentando...",
|
||||||
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing parece estar experimentando un problema al procesar su solicitud. Por favor, recargue el navegador o reinicie Syncthing si el problema persiste.",
|
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing parece estar experimentando un problema al procesar su solicitud. Por favor, recargue el navegador o reinicie Syncthing si el problema persiste.",
|
||||||
"The Syncthing admin interface is configured to allow remote access without a password.": "The Syncthing admin interface is configured to allow remote access without a password.",
|
"The Syncthing admin interface is configured to allow remote access without a password.": "La interfaz administrativa del Syncthing está configurada para permitir acceso remoto sin una contraseña.",
|
||||||
"The aggregated statistics are publicly available at {%url%}.": "Las estadísticas acumuladas están disponibles públicamente en {{url}}.",
|
"The aggregated statistics are publicly available at {%url%}.": "Las estadísticas acumuladas están disponibles públicamente en {{url}}.",
|
||||||
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "La configuración ha sido guardada pero no activada.\nSyncthing debe reiniciarse para activar la nueva configuración.",
|
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "La configuración ha sido guardada pero no activada.\nSyncthing debe reiniciarse para activar la nueva configuración.",
|
||||||
"The device ID cannot be blank.": "La ID del dispositivo no puede estar en blanco.",
|
"The device ID cannot be blank.": "La ID del dispositivo no puede estar en blanco.",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "The rate limit must be a non-negative number (0: no limit)",
|
"The rate limit must be a non-negative number (0: no limit)": "The rate limit must be a non-negative number (0: no limit)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "El intervalo de reescaneo debe ser un número no negativo de segundos.",
|
"The rescan interval must be a non-negative number of seconds.": "El intervalo de reescaneo debe ser un número no negativo de segundos.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "They are retried automatically and will be synced when the error is resolved.",
|
"They are retried automatically and will be synced when the error is resolved.": "They are retried automatically and will be synced when the error is resolved.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
||||||
"This is a major version upgrade.": "Esta es una actualización de version mayor.",
|
"This is a major version upgrade.": "Esta es una actualización de version mayor.",
|
||||||
"Trash Can File Versioning": "Versiones como cubo de basura",
|
"Trash Can File Versioning": "Versiones como cubo de basura",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Versión",
|
"Version": "Versión",
|
||||||
"Versions Path": "Ruta de versiones",
|
"Versions Path": "Ruta de versiones",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Las versiones se eliminan automáticamente si son mayores de la edad máxima o mayor que el número de archivos permitidos en un intervalo.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Las versiones se eliminan automáticamente si son mayores de la edad máxima o mayor que el número de archivos permitidos en un intervalo.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Al agregar un nuevo dispositivo, tenga en cuenta que este dispositivo se debe agregar en el otro lado también.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Al agregar un nuevo dispositivo, tenga en cuenta que este dispositivo se debe agregar en el otro lado también.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Al agregar un nuevo repositorio, tenga en cuenta que la ID del repositorio se utiliza para conectar los repositorios entre dispositivos. Se distingue entre mayúsculas y minúsculas y debe ser exactamente igual en todos los dispositivos.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Al agregar un nuevo repositorio, tenga en cuenta que la ID del repositorio se utiliza para conectar los repositorios entre dispositivos. Se distingue entre mayúsculas y minúsculas y debe ser exactamente igual en todos los dispositivos.",
|
||||||
"Yes": "Sí",
|
"Yes": "Sí",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "días",
|
"days": "días",
|
||||||
"full documentation": "documentación completa",
|
"full documentation": "documentación completa",
|
||||||
"items": "ítems",
|
"items": "ítems",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} quiere compartir repositorio \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} quiere compartir repositorio \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Lisää",
|
"Add": "Lisää",
|
||||||
"Add Device": "Lisää laite",
|
"Add Device": "Lisää laite",
|
||||||
"Add Folder": "Lisää kansio",
|
"Add Folder": "Lisää kansio",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Lisää uusi kansio?",
|
"Add new folder?": "Lisää uusi kansio?",
|
||||||
"Address": "Osoite",
|
"Address": "Osoite",
|
||||||
"Addresses": "Osoitteet",
|
"Addresses": "Osoitteet",
|
||||||
"Advanced": "Advanced",
|
"Advanced": "Advanced",
|
||||||
"Advanced Configuration": "Advanced Configuration",
|
"Advanced Configuration": "Advanced Configuration",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Kaikki data",
|
"All Data": "Kaikki data",
|
||||||
"Allow Anonymous Usage Reporting?": "Salli anonyymi käyttöraportointi?",
|
"Allow Anonymous Usage Reporting?": "Salli anonyymi käyttöraportointi?",
|
||||||
"Alphabetic": "Alphabetic",
|
"Alphabetic": "Alphabetic",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Yhteysvirhe",
|
"Connection Error": "Yhteysvirhe",
|
||||||
"Copied from elsewhere": "Kopioitu muualta",
|
"Copied from elsewhere": "Kopioitu muualta",
|
||||||
"Copied from original": "Kopioitu alkuperäisestä lähteestä",
|
"Copied from original": "Kopioitu alkuperäisestä lähteestä",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Tekijänoikeus © 2015 seuraavat avustajat:",
|
"Copyright © 2015 the following Contributors:": "Tekijänoikeus © 2015 seuraavat avustajat:",
|
||||||
"Danger!": "Vaara!",
|
"Danger!": "Vaara!",
|
||||||
"Delete": "Poista",
|
"Delete": "Poista",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Tiedostot on suojattu muilla laitteilla tehdyiltä muutoksilta, mutta tällä laitteella tehdyt muutokset lähetetään muuhun ryhmään.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Tiedostot on suojattu muilla laitteilla tehdyiltä muutoksilta, mutta tällä laitteella tehdyt muutokset lähetetään muuhun ryhmään.",
|
||||||
"Folder": "Kansio",
|
"Folder": "Kansio",
|
||||||
"Folder ID": "Kansion ID",
|
"Folder ID": "Kansion ID",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Hallitsijakansio",
|
"Folder Master": "Hallitsijakansio",
|
||||||
"Folder Path": "Kansion polku",
|
"Folder Path": "Kansion polku",
|
||||||
"Folders": "Kansiot",
|
"Folders": "Kansiot",
|
||||||
@@ -76,7 +80,7 @@
|
|||||||
"Generate": "Generoi",
|
"Generate": "Generoi",
|
||||||
"Global Discovery": "Globaali etsintä",
|
"Global Discovery": "Globaali etsintä",
|
||||||
"Global Discovery Server": "Globaali etsintäpalvelin",
|
"Global Discovery Server": "Globaali etsintäpalvelin",
|
||||||
"Global Discovery Servers": "Global Discovery Servers",
|
"Global Discovery Servers": "Globaalit etsintäpalvelimet",
|
||||||
"Global State": "Globaali tila",
|
"Global State": "Globaali tila",
|
||||||
"Help": "Apua",
|
"Help": "Apua",
|
||||||
"Home page": "Kotisivu",
|
"Home page": "Kotisivu",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Pois",
|
"Off": "Pois",
|
||||||
"Oldest First": "Vanhin ensin",
|
"Oldest First": "Vanhin ensin",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Options",
|
"Options": "Options",
|
||||||
"Out of Sync": "Ei ajan tasalla",
|
"Out of Sync": "Ei ajan tasalla",
|
||||||
"Out of Sync Items": "Kohteet, jotka eivät ole ajan tasalla",
|
"Out of Sync Items": "Kohteet, jotka eivät ole ajan tasalla",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Käytetty välityspalvelin",
|
"Relayed via": "Käytetty välityspalvelin",
|
||||||
"Relays": "Välityspalvelimet",
|
"Relays": "Välityspalvelimet",
|
||||||
"Release Notes": "Julkaisutiedot",
|
"Release Notes": "Julkaisutiedot",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Poista",
|
"Remove": "Poista",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Skannaa uudelleen",
|
"Rescan": "Skannaa uudelleen",
|
||||||
"Rescan All": "Skannaa kaikki uudelleen",
|
"Rescan All": "Skannaa kaikki uudelleen",
|
||||||
"Rescan Interval": "Uudelleenskannauksen aikaväli",
|
"Rescan Interval": "Uudelleenskannauksen aikaväli",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "Nopeusrajan tulee olla positiivinen luku tai nolla. (0: ei rajaa)",
|
"The rate limit must be a non-negative number (0: no limit)": "Nopeusrajan tulee olla positiivinen luku tai nolla. (0: ei rajaa)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Uudelleenskannauksen aikavälin tulee olla ei-negatiivinen numero sekunteja.",
|
"The rescan interval must be a non-negative number of seconds.": "Uudelleenskannauksen aikavälin tulee olla ei-negatiivinen numero sekunteja.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "They are retried automatically and will be synced when the error is resolved.",
|
"They are retried automatically and will be synced when the error is resolved.": "They are retried automatically and will be synced when the error is resolved.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Tämä voi helposti sallia vihamielisille tahoille pääsyn lukea ja muokata kaikkia tiedostojasi",
|
"This can easily give hackers access to read and change any files on your computer.": "Tämä voi helposti sallia vihamielisille tahoille pääsyn lukea ja muokata kaikkia tiedostojasi",
|
||||||
"This is a major version upgrade.": "Tämä on pääversion päivitys.",
|
"This is a major version upgrade.": "Tämä on pääversion päivitys.",
|
||||||
"Trash Can File Versioning": "Roskakorin tiedostoversiointi",
|
"Trash Can File Versioning": "Roskakorin tiedostoversiointi",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Versio",
|
"Version": "Versio",
|
||||||
"Versions Path": "Versioiden polku",
|
"Versions Path": "Versioiden polku",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versiot poistetaan automaattisesti mikäli ne ovat vanhempia kuin maksimi-ikä tai niiden määrä ylittää sallitun määrän tietyllä aikavälillä.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versiot poistetaan automaattisesti mikäli ne ovat vanhempia kuin maksimi-ikä tai niiden määrä ylittää sallitun määrän tietyllä aikavälillä.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Lisättäessä laitetta, muista että tämä laite tulee myös lisätä toiseen laitteeseen.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Lisättäessä laitetta, muista että tämä laite tulee myös lisätä toiseen laitteeseen.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Lisättäessä uutta kansiota, muista että kansion ID:tä käytetään solmimaan kansiot yhteen laitteiden välillä. Ne ovat riippuvaisia kirjankoosta ja niiden tulee täsmätä kaikkien laitteiden välillä.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Lisättäessä uutta kansiota, muista että kansion ID:tä käytetään solmimaan kansiot yhteen laitteiden välillä. Ne ovat riippuvaisia kirjankoosta ja niiden tulee täsmätä kaikkien laitteiden välillä.",
|
||||||
"Yes": "Kyllä",
|
"Yes": "Kyllä",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "päivää",
|
"days": "päivää",
|
||||||
"full documentation": "täysi dokumentaatio",
|
"full documentation": "täysi dokumentaatio",
|
||||||
"items": "kohteet",
|
"items": "kohteet",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} haluaa jakaa kansion \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} haluaa jakaa kansion \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Ajouter",
|
"Add": "Ajouter",
|
||||||
"Add Device": "Ajouter un périphérique",
|
"Add Device": "Ajouter un périphérique",
|
||||||
"Add Folder": "Ajouter un répertoire",
|
"Add Folder": "Ajouter un répertoire",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Ajouter un nouveau dossier ?",
|
"Add new folder?": "Ajouter un nouveau dossier ?",
|
||||||
"Address": "Adresse",
|
"Address": "Adresse",
|
||||||
"Addresses": "Adresses",
|
"Addresses": "Adresses",
|
||||||
"Advanced": "Avancé",
|
"Advanced": "Avancé",
|
||||||
"Advanced Configuration": "Configuration avancée",
|
"Advanced Configuration": "Configuration avancée",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Toutes les données",
|
"All Data": "Toutes les données",
|
||||||
"Allow Anonymous Usage Reporting?": "Autoriser le rapport anonyme de statistiques d'utilisation ?",
|
"Allow Anonymous Usage Reporting?": "Autoriser le rapport anonyme de statistiques d'utilisation ?",
|
||||||
"Alphabetic": "Alphabétique",
|
"Alphabetic": "Alphabétique",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Erreur de connexion",
|
"Connection Error": "Erreur de connexion",
|
||||||
"Copied from elsewhere": "Copié d'ailleurs",
|
"Copied from elsewhere": "Copié d'ailleurs",
|
||||||
"Copied from original": "Copié depuis l'original",
|
"Copied from original": "Copié depuis l'original",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 Les contributeurs suivants:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 Les contributeurs suivants:",
|
||||||
"Danger!": "Danger!",
|
"Danger!": "Danger!",
|
||||||
"Delete": "Supprimer",
|
"Delete": "Supprimer",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Les fichiers sont protégés des changements réalisés sur les autres appareils, mais les changements réalisés sur cet appareil seront transférés aux autres appareils.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Les fichiers sont protégés des changements réalisés sur les autres appareils, mais les changements réalisés sur cet appareil seront transférés aux autres appareils.",
|
||||||
"Folder": "Dossier",
|
"Folder": "Dossier",
|
||||||
"Folder ID": "ID du répertoire",
|
"Folder ID": "ID du répertoire",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Répertoire maître",
|
"Folder Master": "Répertoire maître",
|
||||||
"Folder Path": "Chemin du répertoire",
|
"Folder Path": "Chemin du répertoire",
|
||||||
"Folders": "Dossiers",
|
"Folders": "Dossiers",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Éteint",
|
"Off": "Éteint",
|
||||||
"Oldest First": "Les plus anciens en premier",
|
"Oldest First": "Les plus anciens en premier",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Options",
|
"Options": "Options",
|
||||||
"Out of Sync": "Désynchronisé",
|
"Out of Sync": "Désynchronisé",
|
||||||
"Out of Sync Items": "Objets non synchronisés",
|
"Out of Sync Items": "Objets non synchronisés",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Relayée par",
|
"Relayed via": "Relayée par",
|
||||||
"Relays": "Relais",
|
"Relays": "Relais",
|
||||||
"Release Notes": "Notes de version",
|
"Release Notes": "Notes de version",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Enlever",
|
"Remove": "Enlever",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Rescanner",
|
"Rescan": "Rescanner",
|
||||||
"Rescan All": "Réanalyser tout",
|
"Rescan All": "Réanalyser tout",
|
||||||
"Rescan Interval": "Intervalle de scan",
|
"Rescan Interval": "Intervalle de scan",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "La limite de débit ne doit pas être négative (0: Aucune limite)",
|
"The rate limit must be a non-negative number (0: no limit)": "La limite de débit ne doit pas être négative (0: Aucune limite)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "L'intervalle d'analyse ne doit pas être un nombre négatif de secondes.",
|
"The rescan interval must be a non-negative number of seconds.": "L'intervalle d'analyse ne doit pas être un nombre négatif de secondes.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Ils seront réessayés automatiquement et synchronisés quand l'erreur sera résolue.",
|
"They are retried automatically and will be synced when the error is resolved.": "Ils seront réessayés automatiquement et synchronisés quand l'erreur sera résolue.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
||||||
"This is a major version upgrade.": "Ceci est une mise à jour majeure.",
|
"This is a major version upgrade.": "Ceci est une mise à jour majeure.",
|
||||||
"Trash Can File Versioning": "Gestion des versions de fichier style poubelle.",
|
"Trash Can File Versioning": "Gestion des versions de fichier style poubelle.",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Version",
|
"Version": "Version",
|
||||||
"Versions Path": "Emplacement des versions",
|
"Versions Path": "Emplacement des versions",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Les versions seront supprimées automatiquement, si elles dépassent la durée maximum de conservation, ou si leur nombre est supérieur à la valeur autorisée dans l'intervalle.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Les versions seront supprimées automatiquement, si elles dépassent la durée maximum de conservation, ou si leur nombre est supérieur à la valeur autorisée dans l'intervalle.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Lorsqu'un appareil est ajouté, gardez à l'esprit que cet appareil doit aussi être ajouté de l'autre coté.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Lorsqu'un appareil est ajouté, gardez à l'esprit que cet appareil doit aussi être ajouté de l'autre coté.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Lorsqu'un nouveau répertoire est ajouté, gardez à l'esprit que son ID est utilisé pour lier les répertoires à travers les appareils. Les ID sont sensibles à la casse et doivent être identiques à travers tous les nœuds.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Lorsqu'un nouveau répertoire est ajouté, gardez à l'esprit que son ID est utilisé pour lier les répertoires à travers les appareils. Les ID sont sensibles à la casse et doivent être identiques à travers tous les nœuds.",
|
||||||
"Yes": "Oui",
|
"Yes": "Oui",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "Jours",
|
"days": "Jours",
|
||||||
"full documentation": "documentation complète",
|
"full documentation": "documentation complète",
|
||||||
"items": "éléments",
|
"items": "éléments",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} veut partager le dossier \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} veut partager le dossier \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,17 +8,19 @@
|
|||||||
"Add": "Ajouter",
|
"Add": "Ajouter",
|
||||||
"Add Device": "Ajouter une machine",
|
"Add Device": "Ajouter une machine",
|
||||||
"Add Folder": "Ajouter un dossier",
|
"Add Folder": "Ajouter un dossier",
|
||||||
|
"Add Remote Device": "Ajouter une machine distante",
|
||||||
"Add new folder?": "Ajouter un nouveau dossier ?",
|
"Add new folder?": "Ajouter un nouveau dossier ?",
|
||||||
"Address": "Adresse",
|
"Address": "Adresse",
|
||||||
"Addresses": "Adresses",
|
"Addresses": "Adresses",
|
||||||
"Advanced": "Avancé",
|
"Advanced": "Avancé",
|
||||||
"Advanced Configuration": "Configuration avancée",
|
"Advanced Configuration": "Configuration avancée",
|
||||||
|
"Advanced settings": "Configuration avancée",
|
||||||
"All Data": "Toutes les données",
|
"All Data": "Toutes les données",
|
||||||
"Allow Anonymous Usage Reporting?": "Autoriser le rapport anonyme de statistiques d'utilisation ?",
|
"Allow Anonymous Usage Reporting?": "Autoriser le rapport anonyme de statistiques d'utilisation ?",
|
||||||
"Alphabetic": "Alphabétique",
|
"Alphabetic": "Alphabétique",
|
||||||
"An external command handles the versioning. It has to remove the file from the synced folder.": "Une commande externe gère les versions de fichiers. Elle supprime les fichiers dans le dossier synchronisé.",
|
"An external command handles the versioning. It has to remove the file from the synced folder.": "Une commande externe gère les versions de fichiers. Elle supprime les fichiers dans le dossier synchronisé.",
|
||||||
"Anonymous Usage Reporting": "Rapport anonyme de statistiques d'utilisation",
|
"Anonymous Usage Reporting": "Rapport anonyme de statistiques d'utilisation",
|
||||||
"Any devices configured on an introducer device will be added to this device as well.": "Toute machine ajoutée depuis une machine introductrice sera aussi ajoutée sur cette machine.",
|
"Any devices configured on an introducer device will be added to this device as well.": "Toute machine ajoutée depuis une machine initiatrice sera aussi ajoutée sur cette machine.",
|
||||||
"Automatic upgrades": "Mises à jour automatiques",
|
"Automatic upgrades": "Mises à jour automatiques",
|
||||||
"Be careful!": "Faites attention !",
|
"Be careful!": "Faites attention !",
|
||||||
"Bugs": "Bugs",
|
"Bugs": "Bugs",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Erreur de connexion",
|
"Connection Error": "Erreur de connexion",
|
||||||
"Copied from elsewhere": "Copié d'ailleurs",
|
"Copied from elsewhere": "Copié d'ailleurs",
|
||||||
"Copied from original": "Copié depuis l'original",
|
"Copied from original": "Copié depuis l'original",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016, les contributeurs suivants:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 Les contributeurs suivants:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 Les contributeurs suivants:",
|
||||||
"Danger!": "Attention !",
|
"Danger!": "Attention !",
|
||||||
"Delete": "Supprimer",
|
"Delete": "Supprimer",
|
||||||
@@ -44,7 +47,7 @@
|
|||||||
"Disconnected": "Déconnecté",
|
"Disconnected": "Déconnecté",
|
||||||
"Discovery": "Découverte",
|
"Discovery": "Découverte",
|
||||||
"Documentation": "Documentation",
|
"Documentation": "Documentation",
|
||||||
"Download Rate": "Débit de réception",
|
"Download Rate": "Vitesse de réception",
|
||||||
"Downloaded": "Téléchargé",
|
"Downloaded": "Téléchargé",
|
||||||
"Downloading": "En cours de téléchargement",
|
"Downloading": "En cours de téléchargement",
|
||||||
"Edit": "Éditer",
|
"Edit": "Éditer",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Les fichiers sont protégés des changements réalisés sur les autres machines, mais les changements réalisés sur celle-ci seront transférés aux autres machines.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Les fichiers sont protégés des changements réalisés sur les autres machines, mais les changements réalisés sur celle-ci seront transférés aux autres machines.",
|
||||||
"Folder": "Dossier",
|
"Folder": "Dossier",
|
||||||
"Folder ID": "ID du dossier",
|
"Folder ID": "ID du dossier",
|
||||||
|
"Folder Label": "Étiquette du dossier",
|
||||||
"Folder Master": "Dossier maître",
|
"Folder Master": "Dossier maître",
|
||||||
"Folder Path": "Chemin du dossier",
|
"Folder Path": "Chemin du dossier",
|
||||||
"Folders": "Dossiers",
|
"Folders": "Dossiers",
|
||||||
@@ -83,7 +87,7 @@
|
|||||||
"Ignore": "Ignorer",
|
"Ignore": "Ignorer",
|
||||||
"Ignore Patterns": "Modèles à éviter",
|
"Ignore Patterns": "Modèles à éviter",
|
||||||
"Ignore Permissions": "Ignorer les permissions",
|
"Ignore Permissions": "Ignorer les permissions",
|
||||||
"Incoming Rate Limit (KiB/s)": "Limite du débit entrant (KiB/s)",
|
"Incoming Rate Limit (KiB/s)": "Limite du débit de réception (Ko/s)",
|
||||||
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Une configuration incorrecte peut créer des dommages dans vos dossiers et mettre hors-service Syncthing",
|
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Une configuration incorrecte peut créer des dommages dans vos dossiers et mettre hors-service Syncthing",
|
||||||
"Introducer": "Initiateur",
|
"Introducer": "Initiateur",
|
||||||
"Inversion of the given condition (i.e. do not exclude)": "Inverser la condition donnée (i.e. ne pas exclure)",
|
"Inversion of the given condition (i.e. do not exclude)": "Inverser la condition donnée (i.e. ne pas exclure)",
|
||||||
@@ -111,10 +115,11 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Éteint",
|
"Off": "Éteint",
|
||||||
"Oldest First": "Les plus anciens en premier",
|
"Oldest First": "Les plus anciens en premier",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Étiquette optionnelle pour le dossier. Peut être différente pour chaque machine.",
|
||||||
"Options": "Options",
|
"Options": "Options",
|
||||||
"Out of Sync": "Désynchronisé",
|
"Out of Sync": "Désynchronisé",
|
||||||
"Out of Sync Items": "Fichiers non synchronisés",
|
"Out of Sync Items": "Fichiers non synchronisés",
|
||||||
"Outgoing Rate Limit (KiB/s)": "Limite du débit sortant (KiB/s)",
|
"Outgoing Rate Limit (KiB/s)": "Limite du débit d'émission (Ko/s)",
|
||||||
"Override Changes": "Écraser les changements",
|
"Override Changes": "Écraser les changements",
|
||||||
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Le chemin du dossier sur l'ordinateur local sera créé si il n'existe pas. Le caractère tilde (~) peut être utilisé comme raccourci vers",
|
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Le chemin du dossier sur l'ordinateur local sera créé si il n'existe pas. Le caractère tilde (~) peut être utilisé comme raccourci vers",
|
||||||
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Chemin où les versions doivent être conservées (laisser vide pour le chemin par défaut de .stversions dans le répertoire)",
|
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Chemin où les versions doivent être conservées (laisser vide pour le chemin par défaut de .stversions dans le répertoire)",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Relayée par",
|
"Relayed via": "Relayée par",
|
||||||
"Relays": "Relais",
|
"Relays": "Relais",
|
||||||
"Release Notes": "Notes de version",
|
"Release Notes": "Notes de version",
|
||||||
|
"Remote Devices": "Machines distantes",
|
||||||
"Remove": "Enlever",
|
"Remove": "Enlever",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Identifiant pour le dossier. Doit être le même sur l'ensemble des machines du cluster.",
|
||||||
"Rescan": "Réanalyse",
|
"Rescan": "Réanalyse",
|
||||||
"Rescan All": "Réanalyser tout",
|
"Rescan All": "Réanalyser tout",
|
||||||
"Rescan Interval": "Intervalle d'analyse",
|
"Rescan Interval": "Intervalle d'analyse",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "La limite de débit ne doit pas être négative (0: Aucune limite)",
|
"The rate limit must be a non-negative number (0: no limit)": "La limite de débit ne doit pas être négative (0: Aucune limite)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "L'intervalle d'analyse ne doit pas être un nombre négatif de secondes.",
|
"The rescan interval must be a non-negative number of seconds.": "L'intervalle d'analyse ne doit pas être un nombre négatif de secondes.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Ils seront réessayés automatiquement et synchronisés quand l'erreur sera résolue.",
|
"They are retried automatically and will be synced when the error is resolved.": "Ils seront réessayés automatiquement et synchronisés quand l'erreur sera résolue.",
|
||||||
|
"This Device": "Cette machine",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Cela permet facilement aux pirates de lire et modifier n'importe quel fichier de votre machine.",
|
"This can easily give hackers access to read and change any files on your computer.": "Cela permet facilement aux pirates de lire et modifier n'importe quel fichier de votre machine.",
|
||||||
"This is a major version upgrade.": "Ceci est une mise à jour majeure.",
|
"This is a major version upgrade.": "Ceci est une mise à jour majeure.",
|
||||||
"Trash Can File Versioning": "Gestion des versions de fichier style poubelle.",
|
"Trash Can File Versioning": "Gestion des versions de fichier style poubelle.",
|
||||||
@@ -214,12 +222,13 @@
|
|||||||
"Upgrade": "Mettre à jour",
|
"Upgrade": "Mettre à jour",
|
||||||
"Upgrade To {%version%}": "Mettre à jour vers {{version}}",
|
"Upgrade To {%version%}": "Mettre à jour vers {{version}}",
|
||||||
"Upgrading": "Mise à jour de Syncthing",
|
"Upgrading": "Mise à jour de Syncthing",
|
||||||
"Upload Rate": "Débit d'envoi",
|
"Upload Rate": "Vitesse d'émission",
|
||||||
"Uptime": "Durée de fonctionnement",
|
"Uptime": "Durée de fonctionnement",
|
||||||
"Use HTTPS for GUI": "Utiliser l'HTTPS pour le GUI",
|
"Use HTTPS for GUI": "Utiliser l'HTTPS pour le GUI",
|
||||||
"Version": "Version",
|
"Version": "Version",
|
||||||
"Versions Path": "Emplacement des versions",
|
"Versions Path": "Emplacement des versions",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Les versions seront supprimées automatiquement, si elles dépassent la durée maximum de conservation, ou si leur nombre est supérieur à la valeur autorisée dans l'intervalle.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Les versions seront supprimées automatiquement, si elles dépassent la durée maximum de conservation, ou si leur nombre est supérieur à la valeur autorisée dans l'intervalle.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Attention, ce chemin est un sous-répertoire du dossier existant \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Lorsqu'une machine est ajoutée, gardez à l'esprit que cette machine doit aussi être ajoutée de l'autre coté.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Lorsqu'une machine est ajoutée, gardez à l'esprit que cette machine doit aussi être ajoutée de l'autre coté.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Lorsqu'un nouveau dossier est ajouté, gardez à l'esprit que son ID est utilisé pour lier les dossiers à travers les machines. Les ID sont sensibles à la casse et doivent être identiques à travers tous les nœuds.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Lorsqu'un nouveau dossier est ajouté, gardez à l'esprit que son ID est utilisé pour lier les dossiers à travers les machines. Les ID sont sensibles à la casse et doivent être identiques à travers tous les nœuds.",
|
||||||
"Yes": "Oui",
|
"Yes": "Oui",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "Jours",
|
"days": "Jours",
|
||||||
"full documentation": "documentation complète",
|
"full documentation": "documentation complète",
|
||||||
"items": "fichiers",
|
"items": "fichiers",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} veut partager le dossier \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} veut partager le dossier \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} veut partager le dossier \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Taheakje",
|
"Add": "Taheakje",
|
||||||
"Add Device": "Apparaat taheakje",
|
"Add Device": "Apparaat taheakje",
|
||||||
"Add Folder": "Map taheakje",
|
"Add Folder": "Map taheakje",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Nije map taheakje?",
|
"Add new folder?": "Nije map taheakje?",
|
||||||
"Address": "Adres",
|
"Address": "Adres",
|
||||||
"Addresses": "Adressen",
|
"Addresses": "Adressen",
|
||||||
"Advanced": "Avansearre",
|
"Advanced": "Avansearre",
|
||||||
"Advanced Configuration": "Avansearre konfiguraasje",
|
"Advanced Configuration": "Avansearre konfiguraasje",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Alle data",
|
"All Data": "Alle data",
|
||||||
"Allow Anonymous Usage Reporting?": "Anonime brûkensrapportaazje tastean?",
|
"Allow Anonymous Usage Reporting?": "Anonime brûkensrapportaazje tastean?",
|
||||||
"Alphabetic": "Alfabetysk",
|
"Alphabetic": "Alfabetysk",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Ferbiningsflater",
|
"Connection Error": "Ferbiningsflater",
|
||||||
"Copied from elsewhere": "Oernommen fan earne oars",
|
"Copied from elsewhere": "Oernommen fan earne oars",
|
||||||
"Copied from original": "Oernommen fan orizjineel",
|
"Copied from original": "Oernommen fan orizjineel",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 de folgende bydragers:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 de folgende bydragers:",
|
||||||
"Danger!": "Gefaar!",
|
"Danger!": "Gefaar!",
|
||||||
"Delete": "Fuortsmite",
|
"Delete": "Fuortsmite",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Triemen binne ymmún foar feroarings makke troch oare apparaten, mar feroarings makke op dit apparaat wurde nei de rest ferstjoerd.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Triemen binne ymmún foar feroarings makke troch oare apparaten, mar feroarings makke op dit apparaat wurde nei de rest ferstjoerd.",
|
||||||
"Folder": "Map",
|
"Folder": "Map",
|
||||||
"Folder ID": "Map-ID",
|
"Folder ID": "Map-ID",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Map-master",
|
"Folder Master": "Map-master",
|
||||||
"Folder Path": "Map-paad",
|
"Folder Path": "Map-paad",
|
||||||
"Folders": "Mappen",
|
"Folders": "Mappen",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "Okee",
|
"OK": "Okee",
|
||||||
"Off": "Ut",
|
"Off": "Ut",
|
||||||
"Oldest First": "Aldste earst",
|
"Oldest First": "Aldste earst",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Opsjes",
|
"Options": "Opsjes",
|
||||||
"Out of Sync": "Net syngronisearre",
|
"Out of Sync": "Net syngronisearre",
|
||||||
"Out of Sync Items": "Net syngronisearre items",
|
"Out of Sync Items": "Net syngronisearre items",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Trochjûn fia",
|
"Relayed via": "Trochjûn fia",
|
||||||
"Relays": "Trochjouers",
|
"Relays": "Trochjouers",
|
||||||
"Release Notes": "Utjeftenotysjes",
|
"Release Notes": "Utjeftenotysjes",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Fuortsmite",
|
"Remove": "Fuortsmite",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Sken opnij",
|
"Rescan": "Sken opnij",
|
||||||
"Rescan All": "Sken alles opnij",
|
"Rescan All": "Sken alles opnij",
|
||||||
"Rescan Interval": "Wersken ynterval",
|
"Rescan Interval": "Wersken ynterval",
|
||||||
@@ -169,7 +176,7 @@
|
|||||||
"Statistics": "Statistiken",
|
"Statistics": "Statistiken",
|
||||||
"Stopped": "Stoppe",
|
"Stopped": "Stoppe",
|
||||||
"Support": "Understeuning",
|
"Support": "Understeuning",
|
||||||
"Sync Protocol Listen Addresses": "Sync-protokol harkadres",
|
"Sync Protocol Listen Addresses": "Sync-protokolharkadressen",
|
||||||
"Syncing": "Oan it Syncen",
|
"Syncing": "Oan it Syncen",
|
||||||
"Syncthing has been shut down.": "Syncthing is útsetten",
|
"Syncthing has been shut down.": "Syncthing is útsetten",
|
||||||
"Syncthing includes the following software or portions thereof:": "Syncthing befettet de folgende sêftguod of parten dêrfan:",
|
"Syncthing includes the following software or portions thereof:": "Syncthing befettet de folgende sêftguod of parten dêrfan:",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "It fluggenslimyt moat in posityf nûmer wêze (0: gjin limyt)",
|
"The rate limit must be a non-negative number (0: no limit)": "It fluggenslimyt moat in posityf nûmer wêze (0: gjin limyt)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "It wersken-ynterfal moat in posityf tal fan sekonden wêze.",
|
"The rescan interval must be a non-negative number of seconds.": "It wersken-ynterfal moat in posityf tal fan sekonden wêze.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Sy wurde automatysk opnij probearre en sille syngronisearre wurde wannear at de flater oplost is.",
|
"They are retried automatically and will be synced when the error is resolved.": "Sy wurde automatysk opnij probearre en sille syngronisearre wurde wannear at de flater oplost is.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Dit kin samar ynkringers (hackers) tagong jaan om elke triem op jo kompjûter te besjen en te feroarjen.",
|
"This can easily give hackers access to read and change any files on your computer.": "Dit kin samar ynkringers (hackers) tagong jaan om elke triem op jo kompjûter te besjen en te feroarjen.",
|
||||||
"This is a major version upgrade.": "Dit is in wichtige ferzjefernijing.",
|
"This is a major version upgrade.": "Dit is in wichtige ferzjefernijing.",
|
||||||
"Trash Can File Versioning": "Jiskefet-triemferzjebehear",
|
"Trash Can File Versioning": "Jiskefet-triemferzjebehear",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Ferzje",
|
"Version": "Ferzje",
|
||||||
"Versions Path": "Ferzjes-paad",
|
"Versions Path": "Ferzjes-paad",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Ferzjes wurde automatysk fuortsmiten wannear't se âlder binne dan de maksimale âldens of wannear it tal fan triemen yn in ynterval grutter is dan tastean.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Ferzjes wurde automatysk fuortsmiten wannear't se âlder binne dan de maksimale âldens of wannear it tal fan triemen yn in ynterval grutter is dan tastean.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Hâld by it taheakjen fan in nij apparaat yn de holle dat it apparaat oan de oare kant ek taheakke wurde moat. ",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Hâld by it taheakjen fan in nij apparaat yn de holle dat it apparaat oan de oare kant ek taheakke wurde moat. ",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Hâld by it taheakjen fan in nije map yn de holle dat de map-ID brûkt wurd om de mappen tusken apparaten mei-inoar te ferbinen. Se binne haadlettergefoelich en moatte oer alle apparaten eksakt oerienkomme.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Hâld by it taheakjen fan in nije map yn de holle dat de map-ID brûkt wurd om de mappen tusken apparaten mei-inoar te ferbinen. Se binne haadlettergefoelich en moatte oer alle apparaten eksakt oerienkomme.",
|
||||||
"Yes": "Ja",
|
"Yes": "Ja",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "dagen",
|
"days": "dagen",
|
||||||
"full documentation": "komplete dokumintaasje",
|
"full documentation": "komplete dokumintaasje",
|
||||||
"items": "items",
|
"items": "items",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} wol map \"{{folder}}\" diele."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} wol map \"{{folder}}\" diele.",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Hozzáadás",
|
"Add": "Hozzáadás",
|
||||||
"Add Device": "Eszköz hozzáadása",
|
"Add Device": "Eszköz hozzáadása",
|
||||||
"Add Folder": "Mappa hozzáadása",
|
"Add Folder": "Mappa hozzáadása",
|
||||||
|
"Add Remote Device": "Távoli eszköz hozzáadása",
|
||||||
"Add new folder?": " Új mappa hozzáadás?",
|
"Add new folder?": " Új mappa hozzáadás?",
|
||||||
"Address": "Cím",
|
"Address": "Cím",
|
||||||
"Addresses": "Címek",
|
"Addresses": "Címek",
|
||||||
"Advanced": "Haladó",
|
"Advanced": "Haladó",
|
||||||
"Advanced Configuration": "Haladó beállítások",
|
"Advanced Configuration": "Haladó beállítások",
|
||||||
|
"Advanced settings": "Haladó beállítások",
|
||||||
"All Data": "Minden adat",
|
"All Data": "Minden adat",
|
||||||
"Allow Anonymous Usage Reporting?": "Engedélyezed a névtelen felhasználási adatok küldését?",
|
"Allow Anonymous Usage Reporting?": "Engedélyezed a névtelen felhasználási adatok küldését?",
|
||||||
"Alphabetic": "ABC rendben",
|
"Alphabetic": "ABC rendben",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Kapcsolódási hiba",
|
"Connection Error": "Kapcsolódási hiba",
|
||||||
"Copied from elsewhere": "Másolva máshonnan",
|
"Copied from elsewhere": "Másolva máshonnan",
|
||||||
"Copied from original": "Másolva az eredetiről",
|
"Copied from original": "Másolva az eredetiről",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Szerzői jog © 2014-2016 az alábbi közreműködők:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 az alábbi közreműködők:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 az alábbi közreműködők:",
|
||||||
"Danger!": "Veszély!",
|
"Danger!": "Veszély!",
|
||||||
"Delete": "Törlés",
|
"Delete": "Törlés",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "A fájlok védve vannak a más eszközökön történt változásokkal szemben, de az ezen az eszközön történt változások érvényesek lesznek a többire.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "A fájlok védve vannak a más eszközökön történt változásokkal szemben, de az ezen az eszközön történt változások érvényesek lesznek a többire.",
|
||||||
"Folder": "Mappa",
|
"Folder": "Mappa",
|
||||||
"Folder ID": "Mappa azonosító",
|
"Folder ID": "Mappa azonosító",
|
||||||
|
"Folder Label": "Mappa címke",
|
||||||
"Folder Master": "Központi mappa",
|
"Folder Master": "Központi mappa",
|
||||||
"Folder Path": "Mappa elérési útja",
|
"Folder Path": "Mappa elérési útja",
|
||||||
"Folders": "Mappák",
|
"Folders": "Mappák",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "Rendben",
|
"OK": "Rendben",
|
||||||
"Off": "Kikapcsolva",
|
"Off": "Kikapcsolva",
|
||||||
"Oldest First": "Régebbi először",
|
"Oldest First": "Régebbi először",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "A mappa kiegészítő leírása. Minden eszközön különböző lehet.",
|
||||||
"Options": "Opciók",
|
"Options": "Opciók",
|
||||||
"Out of Sync": "Nincs szinkronban",
|
"Out of Sync": "Nincs szinkronban",
|
||||||
"Out of Sync Items": "Nem szinkronizált elemek",
|
"Out of Sync Items": "Nem szinkronizált elemek",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Közvetítve",
|
"Relayed via": "Közvetítve",
|
||||||
"Relays": "Közvetítések",
|
"Relays": "Közvetítések",
|
||||||
"Release Notes": "Kiadási megjegyzések",
|
"Release Notes": "Kiadási megjegyzések",
|
||||||
|
"Remote Devices": "Távoli eszközök",
|
||||||
"Remove": "Eltávolítás",
|
"Remove": "Eltávolítás",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "A mappa szükséges azonosítója. Minden fürtözött eszközön azonosnak kell lennie.",
|
||||||
"Rescan": "Átnézés",
|
"Rescan": "Átnézés",
|
||||||
"Rescan All": "Összes átnézése",
|
"Rescan All": "Összes átnézése",
|
||||||
"Rescan Interval": "Átnézési intervallum",
|
"Rescan Interval": "Átnézési intervallum",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "Az arány limitnek pozitív számnak kell lennie (0: nincs limit)",
|
"The rate limit must be a non-negative number (0: no limit)": "Az arány limitnek pozitív számnak kell lennie (0: nincs limit)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Az átnézési intervallum nullánál nagyobb másodperc érték kell legyen",
|
"The rescan interval must be a non-negative number of seconds.": "Az átnézési intervallum nullánál nagyobb másodperc érték kell legyen",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "A hiba javítása után automatikusan újra megpróbálja a szinkronizálást.",
|
"They are retried automatically and will be synced when the error is resolved.": "A hiba javítása után automatikusan újra megpróbálja a szinkronizálást.",
|
||||||
|
"This Device": "Ez az eszköz",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Így a hekkerek könnyedén hozzáférhetnek a számítógépen található fájlokhoz. ",
|
"This can easily give hackers access to read and change any files on your computer.": "Így a hekkerek könnyedén hozzáférhetnek a számítógépen található fájlokhoz. ",
|
||||||
"This is a major version upgrade.": "Ez egy főverzió frissítés.",
|
"This is a major version upgrade.": "Ez egy főverzió frissítés.",
|
||||||
"Trash Can File Versioning": "Szemetes fájl verziókövetés",
|
"Trash Can File Versioning": "Szemetes fájl verziókövetés",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Verzió",
|
"Version": "Verzió",
|
||||||
"Versions Path": "Verziók útvonala",
|
"Versions Path": "Verziók útvonala",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "A régi verziók automatikusan törlődnek, amennyiben öregebbek mint a maximum kor, vagy már több van belőlük mint az adott időszakban megtartható maximum.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "A régi verziók automatikusan törlődnek, amennyiben öregebbek mint a maximum kor, vagy már több van belőlük mint az adott időszakban megtartható maximum.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Figyelem, ez az útvonal egy meglévő mappa alkönyvtára \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Amikor új eszközt adsz hozzá, tartsd észben, hogy a másik oldalon ezt az eszközt is hozzá kell adni.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Amikor új eszközt adsz hozzá, tartsd észben, hogy a másik oldalon ezt az eszközt is hozzá kell adni.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Amikor új mappát adsz hozzá, tartsd észben, hogy a mappa azonosító arra való hogy összekösd a mappákat az eszközeiden. Az azonosító kisbetű-nagybetű érzékeny és pontosan egyeznie kell az eszközökön.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Amikor új mappát adsz hozzá, tartsd észben, hogy a mappa azonosító arra való hogy összekösd a mappákat az eszközeiden. Az azonosító kisbetű-nagybetű érzékeny és pontosan egyeznie kell az eszközökön.",
|
||||||
"Yes": "Igen",
|
"Yes": "Igen",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "nap",
|
"days": "nap",
|
||||||
"full documentation": "teljes dokumentáció",
|
"full documentation": "teljes dokumentáció",
|
||||||
"items": "elem",
|
"items": "elem",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} meg szeretné osztani a \"{{folder}}\" nevű mappát."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} meg szeretné osztani a \"{{folder}}\" nevű mappát.",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} meg szeretné osztani \"{{folderLabel}}\" ({{folder}}) mappát."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Tambah",
|
"Add": "Tambah",
|
||||||
"Add Device": "Tambah Perangkat",
|
"Add Device": "Tambah Perangkat",
|
||||||
"Add Folder": "Tambah Folder",
|
"Add Folder": "Tambah Folder",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Tambah folder baru",
|
"Add new folder?": "Tambah folder baru",
|
||||||
"Address": "Alamat",
|
"Address": "Alamat",
|
||||||
"Addresses": "Alamat",
|
"Addresses": "Alamat",
|
||||||
"Advanced": "Tingkat Lanjut",
|
"Advanced": "Tingkat Lanjut",
|
||||||
"Advanced Configuration": "Konfigurasi Tingkat Lanjut",
|
"Advanced Configuration": "Konfigurasi Tingkat Lanjut",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Semua Data",
|
"All Data": "Semua Data",
|
||||||
"Allow Anonymous Usage Reporting?": "Aktifkan Laporan Penggunaan Anonim?",
|
"Allow Anonymous Usage Reporting?": "Aktifkan Laporan Penggunaan Anonim?",
|
||||||
"Alphabetic": "Alfabet",
|
"Alphabetic": "Alfabet",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Koneksi Galat",
|
"Connection Error": "Koneksi Galat",
|
||||||
"Copied from elsewhere": "Tersalin dari tempat lain",
|
"Copied from elsewhere": "Tersalin dari tempat lain",
|
||||||
"Copied from original": "Tersalin dari asal",
|
"Copied from original": "Tersalin dari asal",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Hak cipta © 2015 Kontributor berikut ini:",
|
"Copyright © 2015 the following Contributors:": "Hak cipta © 2015 Kontributor berikut ini:",
|
||||||
"Danger!": "Bahaya!",
|
"Danger!": "Bahaya!",
|
||||||
"Delete": "Hapus",
|
"Delete": "Hapus",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Berkas diproteksi dari perubahan oleh perangkat lain, tetapi perubahan yang dikirim dari perangkat ini akan dikirim ke perangkat lain dalam klaster.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Berkas diproteksi dari perubahan oleh perangkat lain, tetapi perubahan yang dikirim dari perangkat ini akan dikirim ke perangkat lain dalam klaster.",
|
||||||
"Folder": "Folder",
|
"Folder": "Folder",
|
||||||
"Folder ID": "ID Folder",
|
"Folder ID": "ID Folder",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Master Folder",
|
"Folder Master": "Master Folder",
|
||||||
"Folder Path": "Path Folder",
|
"Folder Path": "Path Folder",
|
||||||
"Folders": "Folder",
|
"Folders": "Folder",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Off",
|
"Off": "Off",
|
||||||
"Oldest First": "Oldest First",
|
"Oldest First": "Oldest First",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Options",
|
"Options": "Options",
|
||||||
"Out of Sync": "Out of Sync",
|
"Out of Sync": "Out of Sync",
|
||||||
"Out of Sync Items": "Out of Sync Items",
|
"Out of Sync Items": "Out of Sync Items",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Relayed via",
|
"Relayed via": "Relayed via",
|
||||||
"Relays": "Relays",
|
"Relays": "Relays",
|
||||||
"Release Notes": "Release Notes",
|
"Release Notes": "Release Notes",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Remove",
|
"Remove": "Remove",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Rescan",
|
"Rescan": "Rescan",
|
||||||
"Rescan All": "Rescan All",
|
"Rescan All": "Rescan All",
|
||||||
"Rescan Interval": "Rescan Interval",
|
"Rescan Interval": "Rescan Interval",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "The rate limit must be a non-negative number (0: no limit)",
|
"The rate limit must be a non-negative number (0: no limit)": "The rate limit must be a non-negative number (0: no limit)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "The rescan interval must be a non-negative number of seconds.",
|
"The rescan interval must be a non-negative number of seconds.": "The rescan interval must be a non-negative number of seconds.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "They are retried automatically and will be synced when the error is resolved.",
|
"They are retried automatically and will be synced when the error is resolved.": "They are retried automatically and will be synced when the error is resolved.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
||||||
"This is a major version upgrade.": "This is a major version upgrade.",
|
"This is a major version upgrade.": "This is a major version upgrade.",
|
||||||
"Trash Can File Versioning": "Trash Can File Versioning",
|
"Trash Can File Versioning": "Trash Can File Versioning",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Version",
|
"Version": "Version",
|
||||||
"Versions Path": "Versions Path",
|
"Versions Path": "Versions Path",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "When adding a new device, keep in mind that this device must be added on the other side too.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "When adding a new device, keep in mind that this device must be added on the other side too.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.",
|
||||||
"Yes": "Yes",
|
"Yes": "Yes",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "days",
|
"days": "days",
|
||||||
"full documentation": "full documentation",
|
"full documentation": "full documentation",
|
||||||
"items": "items",
|
"items": "items",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} wants to share folder \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} wants to share folder \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Aggiungi",
|
"Add": "Aggiungi",
|
||||||
"Add Device": "Aggiungi Dispositivo",
|
"Add Device": "Aggiungi Dispositivo",
|
||||||
"Add Folder": "Aggiungi Cartella",
|
"Add Folder": "Aggiungi Cartella",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Aggiungere una nuova cartella?",
|
"Add new folder?": "Aggiungere una nuova cartella?",
|
||||||
"Address": "Indirizzo",
|
"Address": "Indirizzo",
|
||||||
"Addresses": "Indirizzi",
|
"Addresses": "Indirizzi",
|
||||||
"Advanced": "Avanzato",
|
"Advanced": "Avanzato",
|
||||||
"Advanced Configuration": "Configurazione avanzata",
|
"Advanced Configuration": "Configurazione avanzata",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Tutti i Dati",
|
"All Data": "Tutti i Dati",
|
||||||
"Allow Anonymous Usage Reporting?": "Abilitare Statistiche Anonime di Utilizzo?",
|
"Allow Anonymous Usage Reporting?": "Abilitare Statistiche Anonime di Utilizzo?",
|
||||||
"Alphabetic": "Alfabetico",
|
"Alphabetic": "Alfabetico",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Errore di Connessione",
|
"Connection Error": "Errore di Connessione",
|
||||||
"Copied from elsewhere": "Copiato da qualche altra parte",
|
"Copied from elsewhere": "Copiato da qualche altra parte",
|
||||||
"Copied from original": "Copiato dall'originale",
|
"Copied from original": "Copiato dall'originale",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 i seguenti Collaboratori:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 i seguenti Collaboratori:",
|
||||||
"Danger!": "Pericolo!",
|
"Danger!": "Pericolo!",
|
||||||
"Delete": "Elimina",
|
"Delete": "Elimina",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "I file sono protetti dalle modifiche effettuate negli altri dispositivi, ma le modifiche effettuate in questo dispositivo verranno inviate anche al resto del cluster.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "I file sono protetti dalle modifiche effettuate negli altri dispositivi, ma le modifiche effettuate in questo dispositivo verranno inviate anche al resto del cluster.",
|
||||||
"Folder": "Cartella",
|
"Folder": "Cartella",
|
||||||
"Folder ID": "ID Cartella",
|
"Folder ID": "ID Cartella",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Cartella Principale",
|
"Folder Master": "Cartella Principale",
|
||||||
"Folder Path": "Percorso Cartella",
|
"Folder Path": "Percorso Cartella",
|
||||||
"Folders": "Cartelle",
|
"Folders": "Cartelle",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Disattiva",
|
"Off": "Disattiva",
|
||||||
"Oldest First": "Prima il meno recente",
|
"Oldest First": "Prima il meno recente",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Opzioni",
|
"Options": "Opzioni",
|
||||||
"Out of Sync": "Non sincronizzato",
|
"Out of Sync": "Non sincronizzato",
|
||||||
"Out of Sync Items": "Elementi Non Sincronizzati",
|
"Out of Sync Items": "Elementi Non Sincronizzati",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Reindirizzato tramite",
|
"Relayed via": "Reindirizzato tramite",
|
||||||
"Relays": "Servers di reindirizzamento",
|
"Relays": "Servers di reindirizzamento",
|
||||||
"Release Notes": "Note di rilascio",
|
"Release Notes": "Note di rilascio",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Rimuovi",
|
"Remove": "Rimuovi",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Riscansiona",
|
"Rescan": "Riscansiona",
|
||||||
"Rescan All": "Riscansiona Tutto",
|
"Rescan All": "Riscansiona Tutto",
|
||||||
"Rescan Interval": "Intervallo Scansione",
|
"Rescan Interval": "Intervallo Scansione",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "Il limite di banda deve essere un numero non negativo (da 0 a infinito)",
|
"The rate limit must be a non-negative number (0: no limit)": "Il limite di banda deve essere un numero non negativo (da 0 a infinito)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "L'intervallo di scansione deve essere un numero superiore a zero secondi.",
|
"The rescan interval must be a non-negative number of seconds.": "L'intervallo di scansione deve essere un numero superiore a zero secondi.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Verranno effettuati tentativi in automatico e verranno sincronizzati quando l'errore sarà risolto.",
|
"They are retried automatically and will be synced when the error is resolved.": "Verranno effettuati tentativi in automatico e verranno sincronizzati quando l'errore sarà risolto.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Ciò potrebbe facilmente permettere agli hackers accesso alla lettura e modifica di qualunque file del tuo computer.",
|
"This can easily give hackers access to read and change any files on your computer.": "Ciò potrebbe facilmente permettere agli hackers accesso alla lettura e modifica di qualunque file del tuo computer.",
|
||||||
"This is a major version upgrade.": "Questo è un aggiornamento di versione principale",
|
"This is a major version upgrade.": "Questo è un aggiornamento di versione principale",
|
||||||
"Trash Can File Versioning": "Controllo Versione con Cestino",
|
"Trash Can File Versioning": "Controllo Versione con Cestino",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Versione",
|
"Version": "Versione",
|
||||||
"Versions Path": "Percorso Cartella Versioni",
|
"Versions Path": "Percorso Cartella Versioni",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Le versioni vengono eliminate automaticamente se superano la durata massima o il numero di file permessi in un determinato intervallo temporale.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Le versioni vengono eliminate automaticamente se superano la durata massima o il numero di file permessi in un determinato intervallo temporale.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Anche nel nuovo dispositivo devi aggiungere l'ID di questo, con la stessa procedura.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Anche nel nuovo dispositivo devi aggiungere l'ID di questo, con la stessa procedura.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Quando aggiungi una nuova cartella, ricordati che gli ID vengono utilizzati per collegare le cartelle nei dispositivi. Distinguono maiuscole e minuscole e devono corrispondere esattamente su tutti i dispositivi.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Quando aggiungi una nuova cartella, ricordati che gli ID vengono utilizzati per collegare le cartelle nei dispositivi. Distinguono maiuscole e minuscole e devono corrispondere esattamente su tutti i dispositivi.",
|
||||||
"Yes": "Sì",
|
"Yes": "Sì",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "giorni",
|
"days": "giorni",
|
||||||
"full documentation": "documentazione completa",
|
"full documentation": "documentazione completa",
|
||||||
"items": "elementi",
|
"items": "elementi",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} vuole condividere la cartella \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} vuole condividere la cartella \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "追加",
|
"Add": "追加",
|
||||||
"Add Device": "デバイスを追加",
|
"Add Device": "デバイスを追加",
|
||||||
"Add Folder": "フォルダーを追加",
|
"Add Folder": "フォルダーを追加",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "新しいフォルダーとして追加しますか?",
|
"Add new folder?": "新しいフォルダーとして追加しますか?",
|
||||||
"Address": "アドレス",
|
"Address": "アドレス",
|
||||||
"Addresses": "アドレス",
|
"Addresses": "アドレス",
|
||||||
"Advanced": "高度な設定",
|
"Advanced": "高度な設定",
|
||||||
"Advanced Configuration": "高度な設定",
|
"Advanced Configuration": "高度な設定",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "全てのデータ",
|
"All Data": "全てのデータ",
|
||||||
"Allow Anonymous Usage Reporting?": "匿名で利用状況をレポートすることを許可しますか?",
|
"Allow Anonymous Usage Reporting?": "匿名で利用状況をレポートすることを許可しますか?",
|
||||||
"Alphabetic": "アルファベット順",
|
"Alphabetic": "アルファベット順",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "接続エラー",
|
"Connection Error": "接続エラー",
|
||||||
"Copied from elsewhere": "別ファイルからコピー済",
|
"Copied from elsewhere": "別ファイルからコピー済",
|
||||||
"Copied from original": "元ファイルからコピー済",
|
"Copied from original": "元ファイルからコピー済",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
|
||||||
"Danger!": "危険",
|
"Danger!": "危険",
|
||||||
"Delete": "削除",
|
"Delete": "削除",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "ファイルを他のデバイスによる変更から保護します。一方、このデバイスでの変更は他のデバイスに送信されます。",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "ファイルを他のデバイスによる変更から保護します。一方、このデバイスでの変更は他のデバイスに送信されます。",
|
||||||
"Folder": "フォルダー",
|
"Folder": "フォルダー",
|
||||||
"Folder ID": "フォルダーID",
|
"Folder ID": "フォルダーID",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "フォルダーのマスター",
|
"Folder Master": "フォルダーのマスター",
|
||||||
"Folder Path": "フォルダーパス",
|
"Folder Path": "フォルダーパス",
|
||||||
"Folders": "フォルダー",
|
"Folders": "フォルダー",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "オフ",
|
"Off": "オフ",
|
||||||
"Oldest First": "古い順",
|
"Oldest First": "古い順",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "オプション",
|
"Options": "オプション",
|
||||||
"Out of Sync": "未同期",
|
"Out of Sync": "未同期",
|
||||||
"Out of Sync Items": "同期の必要な項目",
|
"Out of Sync Items": "同期の必要な項目",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "経由している中継サーバーのアドレス",
|
"Relayed via": "経由している中継サーバーのアドレス",
|
||||||
"Relays": "中継サーバー",
|
"Relays": "中継サーバー",
|
||||||
"Release Notes": "リリースノート",
|
"Release Notes": "リリースノート",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "除去",
|
"Remove": "除去",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "再スキャン",
|
"Rescan": "再スキャン",
|
||||||
"Rescan All": "すべて再スキャン",
|
"Rescan All": "すべて再スキャン",
|
||||||
"Rescan Interval": "再スキャン間隔",
|
"Rescan Interval": "再スキャン間隔",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "帯域制限の値として負の数は指定できません (0を指定すると無制限になります)。",
|
"The rate limit must be a non-negative number (0: no limit)": "帯域制限の値として負の数は指定できません (0を指定すると無制限になります)。",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "再スキャン間隔として負の数は指定できません。",
|
"The rescan interval must be a non-negative number of seconds.": "再スキャン間隔として負の数は指定できません。",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "エラーが解決すると、自動的に再試行され同期されます。",
|
"They are retried automatically and will be synced when the error is resolved.": "エラーが解決すると、自動的に再試行され同期されます。",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "この設定のままでは、あなたのコンピューターにある任意のファイルを、他者が簡単に盗み見たり書き換えたりすることができます。",
|
"This can easily give hackers access to read and change any files on your computer.": "この設定のままでは、あなたのコンピューターにある任意のファイルを、他者が簡単に盗み見たり書き換えたりすることができます。",
|
||||||
"This is a major version upgrade.": "メジャーアップグレードです。",
|
"This is a major version upgrade.": "メジャーアップグレードです。",
|
||||||
"Trash Can File Versioning": "ゴミ箱によるバージョン管理",
|
"Trash Can File Versioning": "ゴミ箱によるバージョン管理",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "バージョン",
|
"Version": "バージョン",
|
||||||
"Versions Path": "古いバージョンを保存するパス",
|
"Versions Path": "古いバージョンを保存するパス",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "古いバージョンは、最大寿命もしくは期間ごとの最大保存数を超えた場合、自動的に削除されます。",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "古いバージョンは、最大寿命もしくは期間ごとの最大保存数を超えた場合、自動的に削除されます。",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "新しいデバイスを追加する際は、相手側のデバイスにもこのデバイスを追加する必要があることに留意してください。",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "新しいデバイスを追加する際は、相手側のデバイスにもこのデバイスを追加する必要があることに留意してください。",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "新しいフォルダーを追加する際、フォルダーIDはデバイス間でフォルダーの対応づけに使われることに注意してください。フォルダーIDは大文字と小文字が区別され、共有するすべてのデバイスの間で完全に一致しなくてはなりません。",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "新しいフォルダーを追加する際、フォルダーIDはデバイス間でフォルダーの対応づけに使われることに注意してください。フォルダーIDは大文字と小文字が区別され、共有するすべてのデバイスの間で完全に一致しなくてはなりません。",
|
||||||
"Yes": "はい",
|
"Yes": "はい",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "日",
|
"days": "日",
|
||||||
"full documentation": "詳細なマニュアル",
|
"full documentation": "詳細なマニュアル",
|
||||||
"items": "項目",
|
"items": "項目",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} がフォルダー \"{{folder}}\" を共有するよう求めています。"
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} がフォルダー \"{{folder}}\" を共有するよう求めています。",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "추가",
|
"Add": "추가",
|
||||||
"Add Device": "기기 추가",
|
"Add Device": "기기 추가",
|
||||||
"Add Folder": "폴더 추가",
|
"Add Folder": "폴더 추가",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "새로운 폴더를 추가하시겠습니까?",
|
"Add new folder?": "새로운 폴더를 추가하시겠습니까?",
|
||||||
"Address": "주소",
|
"Address": "주소",
|
||||||
"Addresses": "주소",
|
"Addresses": "주소",
|
||||||
"Advanced": "Advanced",
|
"Advanced": "Advanced",
|
||||||
"Advanced Configuration": "Advanced Configuration",
|
"Advanced Configuration": "Advanced Configuration",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "전체 데이터",
|
"All Data": "전체 데이터",
|
||||||
"Allow Anonymous Usage Reporting?": "익명 사용 보고서를 보내시겠습니까?",
|
"Allow Anonymous Usage Reporting?": "익명 사용 보고서를 보내시겠습니까?",
|
||||||
"Alphabetic": "알파벳순",
|
"Alphabetic": "알파벳순",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "연결 에러",
|
"Connection Error": "연결 에러",
|
||||||
"Copied from elsewhere": "다른 곳에서 복사됨",
|
"Copied from elsewhere": "다른 곳에서 복사됨",
|
||||||
"Copied from original": "원본에서 복사됨",
|
"Copied from original": "원본에서 복사됨",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 the following Contributors:",
|
||||||
"Danger!": "Danger!",
|
"Danger!": "Danger!",
|
||||||
"Delete": "삭제",
|
"Delete": "삭제",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "다른 장치가 파일을 편집할 수 없으며 반드시 이 장치의 내용을 기준으로 동기화합니다.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "다른 장치가 파일을 편집할 수 없으며 반드시 이 장치의 내용을 기준으로 동기화합니다.",
|
||||||
"Folder": "Folder",
|
"Folder": "Folder",
|
||||||
"Folder ID": "폴더 ID",
|
"Folder ID": "폴더 ID",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "폴더 소유자",
|
"Folder Master": "폴더 소유자",
|
||||||
"Folder Path": "폴더 경로",
|
"Folder Path": "폴더 경로",
|
||||||
"Folders": "폴더",
|
"Folders": "폴더",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "확인",
|
"OK": "확인",
|
||||||
"Off": "꺼짐",
|
"Off": "꺼짐",
|
||||||
"Oldest First": "오래된 파일순",
|
"Oldest First": "오래된 파일순",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Options",
|
"Options": "Options",
|
||||||
"Out of Sync": "Out of Sync",
|
"Out of Sync": "Out of Sync",
|
||||||
"Out of Sync Items": "동기화되지 않은 항목",
|
"Out of Sync Items": "동기화되지 않은 항목",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Relayed via",
|
"Relayed via": "Relayed via",
|
||||||
"Relays": "Relays",
|
"Relays": "Relays",
|
||||||
"Release Notes": "릴리즈 노트",
|
"Release Notes": "릴리즈 노트",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Remove",
|
"Remove": "Remove",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "재탐색",
|
"Rescan": "재탐색",
|
||||||
"Rescan All": "전체 재탐색",
|
"Rescan All": "전체 재탐색",
|
||||||
"Rescan Interval": "재탐색 간격",
|
"Rescan Interval": "재탐색 간격",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "The rate limit must be a non-negative number (0: no limit)",
|
"The rate limit must be a non-negative number (0: no limit)": "The rate limit must be a non-negative number (0: no limit)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "재검색 간격은 초단위이며 양수로 입력해야 합니다.",
|
"The rescan interval must be a non-negative number of seconds.": "재검색 간격은 초단위이며 양수로 입력해야 합니다.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "They are retried automatically and will be synced when the error is resolved.",
|
"They are retried automatically and will be synced when the error is resolved.": "They are retried automatically and will be synced when the error is resolved.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
||||||
"This is a major version upgrade.": "이 업데이트는 메이저 버전입니다.",
|
"This is a major version upgrade.": "이 업데이트는 메이저 버전입니다.",
|
||||||
"Trash Can File Versioning": "Trash Can File Versioning",
|
"Trash Can File Versioning": "Trash Can File Versioning",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "버전",
|
"Version": "버전",
|
||||||
"Versions Path": "버전 저장 경로",
|
"Versions Path": "버전 저장 경로",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "최대 보존 기간보다 오래되었거나 지정한 개수를 넘긴 버전은 자동으로 삭제됩니다.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "최대 보존 기간보다 오래되었거나 지정한 개수를 넘긴 버전은 자동으로 삭제됩니다.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "새 장치를 추가할 시 추가한 기기 쪽에서도 이 장치를 추가해야 합니다.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "새 장치를 추가할 시 추가한 기기 쪽에서도 이 장치를 추가해야 합니다.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "새 폴더를 추가할 시 폴더 ID는 장치간에 폴더를 묶을 때 사용됩니다. 대소문자를 구분하며 모든 장치에서 같은 ID를 사용해야 합니다.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "새 폴더를 추가할 시 폴더 ID는 장치간에 폴더를 묶을 때 사용됩니다. 대소문자를 구분하며 모든 장치에서 같은 ID를 사용해야 합니다.",
|
||||||
"Yes": "예",
|
"Yes": "예",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "days",
|
"days": "days",
|
||||||
"full documentation": "전체 문서",
|
"full documentation": "전체 문서",
|
||||||
"items": "항목",
|
"items": "항목",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} 에서 폴더 \\\"{{folder}}\\\" 를 공유하길 원합니다."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} 에서 폴더 \\\"{{folder}}\\\" 를 공유하길 원합니다.",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Pridėti",
|
"Add": "Pridėti",
|
||||||
"Add Device": "Pridėti įrenginį",
|
"Add Device": "Pridėti įrenginį",
|
||||||
"Add Folder": "Pridėti aplanką",
|
"Add Folder": "Pridėti aplanką",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Pridėti naują aplanką?",
|
"Add new folder?": "Pridėti naują aplanką?",
|
||||||
"Address": "Adresas",
|
"Address": "Adresas",
|
||||||
"Addresses": "Adresai",
|
"Addresses": "Adresai",
|
||||||
"Advanced": "Pažangus",
|
"Advanced": "Pažangus",
|
||||||
"Advanced Configuration": "Pažangus nustatymai",
|
"Advanced Configuration": "Išplėstinė konfigūracija",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Visiems duomenims",
|
"All Data": "Visiems duomenims",
|
||||||
"Allow Anonymous Usage Reporting?": "Siųsti anonimišką vartojimo ataskaitą?",
|
"Allow Anonymous Usage Reporting?": "Siųsti anonimišką vartojimo ataskaitą?",
|
||||||
"Alphabetic": "Abėcėlės tvarka",
|
"Alphabetic": "Abėcėlės tvarka",
|
||||||
@@ -32,9 +34,10 @@
|
|||||||
"Connection Error": "Susijungimo klaida",
|
"Connection Error": "Susijungimo klaida",
|
||||||
"Copied from elsewhere": "Nukopijuota iš betkur",
|
"Copied from elsewhere": "Nukopijuota iš betkur",
|
||||||
"Copied from original": "Nukopijuota iš originalo",
|
"Copied from original": "Nukopijuota iš originalo",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Visos teisės saugomos © 2015 šių bendraautorių:",
|
"Copyright © 2015 the following Contributors:": "Visos teisės saugomos © 2015 šių bendraautorių:",
|
||||||
"Danger!": "Pavojus!",
|
"Danger!": "Pavojus!",
|
||||||
"Delete": "Trinti",
|
"Delete": "Ištrinti",
|
||||||
"Deleted": "Ištrinta",
|
"Deleted": "Ištrinta",
|
||||||
"Device ID": "Įrenginio ID",
|
"Device ID": "Įrenginio ID",
|
||||||
"Device Identification": "Įrenginio identifikacija",
|
"Device Identification": "Įrenginio identifikacija",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Failai apsaugoti nuo pakeitimų atliktų kituose įrenginiuose, bet pakeitimai šiame įrenginyje bus nusiųsti kitiems.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Failai apsaugoti nuo pakeitimų atliktų kituose įrenginiuose, bet pakeitimai šiame įrenginyje bus nusiųsti kitiems.",
|
||||||
"Folder": "Aplankas",
|
"Folder": "Aplankas",
|
||||||
"Folder ID": "Aplanko ID",
|
"Folder ID": "Aplanko ID",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Aplanko vadovas",
|
"Folder Master": "Aplanko vadovas",
|
||||||
"Folder Path": "Kelias iki apkanko",
|
"Folder Path": "Kelias iki apkanko",
|
||||||
"Folders": "Aplankai",
|
"Folders": "Aplankai",
|
||||||
@@ -111,15 +115,16 @@
|
|||||||
"OK": "Gerai",
|
"OK": "Gerai",
|
||||||
"Off": "Netaikoma",
|
"Off": "Netaikoma",
|
||||||
"Oldest First": "Seniausi pirmiau",
|
"Oldest First": "Seniausi pirmiau",
|
||||||
"Options": "Nustatymai",
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
|
"Options": "Parametrai",
|
||||||
"Out of Sync": "Išsisinchronizavę",
|
"Out of Sync": "Išsisinchronizavę",
|
||||||
"Out of Sync Items": "Nesutikrinta",
|
"Out of Sync Items": "Nesutikrinta",
|
||||||
"Outgoing Rate Limit (KiB/s)": "Išeinančio srauto maksimalus greitis (KiB/s)",
|
"Outgoing Rate Limit (KiB/s)": "Išeinančio srauto maksimalus greitis (KiB/s)",
|
||||||
"Override Changes": "Perrašyti pakeitimus",
|
"Override Changes": "Perrašyti pakeitimus",
|
||||||
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Kelias iki aplanko šiame kompiuteryje. Bus sukurtas, jei neegzistuoja. Tildės simbolis (~) gali būti naudojamas kaip trumpinys",
|
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Kelias iki aplanko šiame kompiuteryje. Bus sukurtas, jei neegzistuoja. Tildės simbolis (~) gali būti naudojamas kaip trumpinys",
|
||||||
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Kelias, kur bus saugomos versijos (palikite tuščią numatytam .stversions aplankui).",
|
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Kelias, kur bus saugomos versijos (palikite tuščią numatytam .stversions aplankui).",
|
||||||
"Pause": "Sustabdyti",
|
"Pause": "Pristabdyti",
|
||||||
"Paused": "Sustabdyta",
|
"Paused": "Pristabdyta",
|
||||||
"Please consult the release notes before performing a major upgrade.": "Peržvelkite laidos informaciją prieš atlikdami stambų atnaujinimą.",
|
"Please consult the release notes before performing a major upgrade.": "Peržvelkite laidos informaciją prieš atlikdami stambų atnaujinimą.",
|
||||||
"Please set a GUI Authentication User and Password in the Settings dialog.": "Prašome nustatymų dialoge nustatyti valdymo skydelio vartotojo vardą ir slaptažodį.",
|
"Please set a GUI Authentication User and Password in the Settings dialog.": "Prašome nustatymų dialoge nustatyti valdymo skydelio vartotojo vardą ir slaptažodį.",
|
||||||
"Please wait": "Prašome palaukti",
|
"Please wait": "Prašome palaukti",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Retransliuojama per",
|
"Relayed via": "Retransliuojama per",
|
||||||
"Relays": "Retransliatoriai",
|
"Relays": "Retransliatoriai",
|
||||||
"Release Notes": "Laidos Informacija",
|
"Release Notes": "Laidos Informacija",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Pašalinti",
|
"Remove": "Pašalinti",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Nuskaityti iš naujo",
|
"Rescan": "Nuskaityti iš naujo",
|
||||||
"Rescan All": "Nuskaityti visus aplankus",
|
"Rescan All": "Nuskaityti visus aplankus",
|
||||||
"Rescan Interval": "Pertrauka tarp nuskaitymų",
|
"Rescan Interval": "Pertrauka tarp nuskaitymų",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "Srauto maksimalus greitis privalo būti ne neigiamas skaičius (0: nėra apribojimo)",
|
"The rate limit must be a non-negative number (0: no limit)": "Srauto maksimalus greitis privalo būti ne neigiamas skaičius (0: nėra apribojimo)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Nuskaitymo dažnis negali būti neigiamas skaičius.",
|
"The rescan interval must be a non-negative number of seconds.": "Nuskaitymo dažnis negali būti neigiamas skaičius.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Failus bus automatiškai badoma parsiųsti dar kartą kai išspręsite klaidas",
|
"They are retried automatically and will be synced when the error is resolved.": "Failus bus automatiškai badoma parsiųsti dar kartą kai išspręsite klaidas",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Tai gali suteikti programišiams lengvą prieigą skaityti ir keisti bet kokius failus jūsų kompiuteryje.",
|
"This can easily give hackers access to read and change any files on your computer.": "Tai gali suteikti programišiams lengvą prieigą skaityti ir keisti bet kokius failus jūsų kompiuteryje.",
|
||||||
"This is a major version upgrade.": "Tai yra stambus atnaujinimas.",
|
"This is a major version upgrade.": "Tai yra stambus atnaujinimas.",
|
||||||
"Trash Can File Versioning": "Šiukšliadėžės versijų valdymas",
|
"Trash Can File Versioning": "Šiukšliadėžės versijų valdymas",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Versija",
|
"Version": "Versija",
|
||||||
"Versions Path": "Kelias iki versijos",
|
"Versions Path": "Kelias iki versijos",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versijos ištrinamos jei senesnės už nustatyta maksimalų amžių arba jei viršytas maksimalus failų skaičius per nustatytą laiko tarpą.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versijos ištrinamos jei senesnės už nustatyta maksimalų amžių arba jei viršytas maksimalus failų skaičius per nustatytą laiko tarpą.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Pridėdami įrenginį, turėkite omeny, kad šis įrenginys taip pat turi būti pridėtas kitoje pusėje.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Pridėdami įrenginį, turėkite omeny, kad šis įrenginys taip pat turi būti pridėtas kitoje pusėje.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Kai įvedate naują aplanką neužmirškite, kad jis bus naudojamas visuose įrenginiuose. Svarbu visur įvesti visiškai tokį pat aplanko vardą neužmirštant apie didžiąsias ir mažąsias raides.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Kai įvedate naują aplanką neužmirškite, kad jis bus naudojamas visuose įrenginiuose. Svarbu visur įvesti visiškai tokį pat aplanko vardą neužmirštant apie didžiąsias ir mažąsias raides.",
|
||||||
"Yes": "Taip",
|
"Yes": "Taip",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "dienos",
|
"days": "dienos",
|
||||||
"full documentation": "pilna dokumentacija",
|
"full documentation": "pilna dokumentacija",
|
||||||
"items": "įrašai",
|
"items": "įrašai",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} nori dalintis aplanku \"{{folder}}\""
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} nori dalintis aplanku \"{{folder}}\"",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Legg til",
|
"Add": "Legg til",
|
||||||
"Add Device": "Legg til Enhet",
|
"Add Device": "Legg til Enhet",
|
||||||
"Add Folder": "Legg til Mappe",
|
"Add Folder": "Legg til Mappe",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Legg til ny mappe?",
|
"Add new folder?": "Legg til ny mappe?",
|
||||||
"Address": "Adresse",
|
"Address": "Adresse",
|
||||||
"Addresses": "Adresser",
|
"Addresses": "Adresser",
|
||||||
"Advanced": "Avansert",
|
"Advanced": "Avansert",
|
||||||
"Advanced Configuration": "Avanserte Innstillinger",
|
"Advanced Configuration": "Avanserte Innstillinger",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Alle data",
|
"All Data": "Alle data",
|
||||||
"Allow Anonymous Usage Reporting?": "Tillat Anonym Innsamling Av Brukerdata?",
|
"Allow Anonymous Usage Reporting?": "Tillat Anonym Innsamling Av Brukerdata?",
|
||||||
"Alphabetic": "Alfabetisk",
|
"Alphabetic": "Alfabetisk",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Tilkoblingsfeil",
|
"Connection Error": "Tilkoblingsfeil",
|
||||||
"Copied from elsewhere": "Kopiert fra et annet sted",
|
"Copied from elsewhere": "Kopiert fra et annet sted",
|
||||||
"Copied from original": "Kopiert fra original",
|
"Copied from original": "Kopiert fra original",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Opphavsrett © 2015 de følgende bidragsytere:",
|
"Copyright © 2015 the following Contributors:": "Opphavsrett © 2015 de følgende bidragsytere:",
|
||||||
"Danger!": "Fare!",
|
"Danger!": "Fare!",
|
||||||
"Delete": "Slett",
|
"Delete": "Slett",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Filer er beskyttet mot endringer som er gjort på andre enheter, men endringer som er gjort på denne enheten blir sendt til resten av gruppen.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Filer er beskyttet mot endringer som er gjort på andre enheter, men endringer som er gjort på denne enheten blir sendt til resten av gruppen.",
|
||||||
"Folder": "Katalog",
|
"Folder": "Katalog",
|
||||||
"Folder ID": "Mappe ID",
|
"Folder ID": "Mappe ID",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Styrende Mappe",
|
"Folder Master": "Styrende Mappe",
|
||||||
"Folder Path": "Mappeplassering",
|
"Folder Path": "Mappeplassering",
|
||||||
"Folders": "Mapper",
|
"Folders": "Mapper",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Av",
|
"Off": "Av",
|
||||||
"Oldest First": "Den eldste først",
|
"Oldest First": "Den eldste først",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Valg",
|
"Options": "Valg",
|
||||||
"Out of Sync": "Ikke synkronisert",
|
"Out of Sync": "Ikke synkronisert",
|
||||||
"Out of Sync Items": "Ikke Synkroniserte Element",
|
"Out of Sync Items": "Ikke Synkroniserte Element",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Relé via",
|
"Relayed via": "Relé via",
|
||||||
"Relays": "Reléer",
|
"Relays": "Reléer",
|
||||||
"Release Notes": "Utgivelsesnotat",
|
"Release Notes": "Utgivelsesnotat",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Fjern",
|
"Remove": "Fjern",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Gjennomsøk på nytt",
|
"Rescan": "Gjennomsøk på nytt",
|
||||||
"Rescan All": "Gjennomsøk alt på nytt",
|
"Rescan All": "Gjennomsøk alt på nytt",
|
||||||
"Rescan Interval": "Intervall for gjennomsøking",
|
"Rescan Interval": "Intervall for gjennomsøking",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "Hastighetsbegrensningen kan ikke være et negativt tall (0: ingen begrensing)",
|
"The rate limit must be a non-negative number (0: no limit)": "Hastighetsbegrensningen kan ikke være et negativt tall (0: ingen begrensing)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Antall sekund for intervallet kan ikke være negativt.",
|
"The rescan interval must be a non-negative number of seconds.": "Antall sekund for intervallet kan ikke være negativt.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Disse hentes automatisk og vil synkroniseres når feilen er blitt utbedret.",
|
"They are retried automatically and will be synced when the error is resolved.": "Disse hentes automatisk og vil synkroniseres når feilen er blitt utbedret.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Dette kan lett gi hackere tilgang til å lese og endre alle filer på datamaskinen din.",
|
"This can easily give hackers access to read and change any files on your computer.": "Dette kan lett gi hackere tilgang til å lese og endre alle filer på datamaskinen din.",
|
||||||
"This is a major version upgrade.": "Dette er en hovedoppgradering",
|
"This is a major version upgrade.": "Dette er en hovedoppgradering",
|
||||||
"Trash Can File Versioning": "Papirkurv Versjonskontroll",
|
"Trash Can File Versioning": "Papirkurv Versjonskontroll",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Versjon",
|
"Version": "Versjon",
|
||||||
"Versions Path": "Plassering Av Versjoner",
|
"Versions Path": "Plassering Av Versjoner",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versjoner blir automatisk slettet når maksimal levetid er nådd eller når antall filer er oversteget.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versjoner blir automatisk slettet når maksimal levetid er nådd eller når antall filer er oversteget.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Merk at når en ny enhet blir lagt til må denne også legges til på andre siden.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Merk at når en ny enhet blir lagt til må denne også legges til på andre siden.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Når en ny mappe blir lagt til, husk at Mappe-ID blir brukt til å binde sammen mapper mellom enheter. Det er forskjell på store og små bokstaver, så IDene må være identiske på alle enhetene.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Når en ny mappe blir lagt til, husk at Mappe-ID blir brukt til å binde sammen mapper mellom enheter. Det er forskjell på store og små bokstaver, så IDene må være identiske på alle enhetene.",
|
||||||
"Yes": "Ja",
|
"Yes": "Ja",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "dager",
|
"days": "dager",
|
||||||
"full documentation": "all dokumentasjon",
|
"full documentation": "all dokumentasjon",
|
||||||
"items": "elementer",
|
"items": "elementer",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} ønsker å dele mappen \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} ønsker å dele mappen \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Toevoegen",
|
"Add": "Toevoegen",
|
||||||
"Add Device": "Apparaat toevoegen",
|
"Add Device": "Apparaat toevoegen",
|
||||||
"Add Folder": "Map toevoegen",
|
"Add Folder": "Map toevoegen",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Voeg nieuwe map toe?",
|
"Add new folder?": "Voeg nieuwe map toe?",
|
||||||
"Address": "Adres",
|
"Address": "Adres",
|
||||||
"Addresses": "Adressen",
|
"Addresses": "Adressen",
|
||||||
"Advanced": "Geavanceerd",
|
"Advanced": "Geavanceerd",
|
||||||
"Advanced Configuration": "Geavanceerde configuratie",
|
"Advanced Configuration": "Geavanceerde configuratie",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Alle gegevens",
|
"All Data": "Alle gegevens",
|
||||||
"Allow Anonymous Usage Reporting?": "Versturen van anonieme gebruikersstatistieken toestaan?",
|
"Allow Anonymous Usage Reporting?": "Versturen van anonieme gebruikersstatistieken toestaan?",
|
||||||
"Alphabetic": "Alfabetisch",
|
"Alphabetic": "Alfabetisch",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Verbindingsfout",
|
"Connection Error": "Verbindingsfout",
|
||||||
"Copied from elsewhere": "Gekopieerd vanaf elders",
|
"Copied from elsewhere": "Gekopieerd vanaf elders",
|
||||||
"Copied from original": "Gekopieerd van het origineel",
|
"Copied from original": "Gekopieerd van het origineel",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 de volgende Bijdragers:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 de volgende Bijdragers:",
|
||||||
"Danger!": "Gevaar!",
|
"Danger!": "Gevaar!",
|
||||||
"Delete": "Verwijderen",
|
"Delete": "Verwijderen",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Bestanden zijn beschermt tegen aanpassingen die gemaakt zijn door andere apparaten, maar aanpassingen op dit apparaat worden doorgestuurd naar de rest van het cluster.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Bestanden zijn beschermt tegen aanpassingen die gemaakt zijn door andere apparaten, maar aanpassingen op dit apparaat worden doorgestuurd naar de rest van het cluster.",
|
||||||
"Folder": "Map",
|
"Folder": "Map",
|
||||||
"Folder ID": "Map-ID",
|
"Folder ID": "Map-ID",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Hoofdmap",
|
"Folder Master": "Hoofdmap",
|
||||||
"Folder Path": "Maplocatie",
|
"Folder Path": "Maplocatie",
|
||||||
"Folders": "Mappen",
|
"Folders": "Mappen",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Uit",
|
"Off": "Uit",
|
||||||
"Oldest First": "Oudste eerst",
|
"Oldest First": "Oudste eerst",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Opties",
|
"Options": "Opties",
|
||||||
"Out of Sync": "Niet gesynchroniseerd",
|
"Out of Sync": "Niet gesynchroniseerd",
|
||||||
"Out of Sync Items": "Niet-gesynchroniseerde items",
|
"Out of Sync Items": "Niet-gesynchroniseerde items",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Doorgestuurd via",
|
"Relayed via": "Doorgestuurd via",
|
||||||
"Relays": "Relais",
|
"Relays": "Relais",
|
||||||
"Release Notes": "Release notes",
|
"Release Notes": "Release notes",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Verwijderen",
|
"Remove": "Verwijderen",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Opnieuw scannen",
|
"Rescan": "Opnieuw scannen",
|
||||||
"Rescan All": "Scan alles opnieuw",
|
"Rescan All": "Scan alles opnieuw",
|
||||||
"Rescan Interval": "Scanfrequentie",
|
"Rescan Interval": "Scanfrequentie",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "De snelheidslimiet moet een positief nummer zijn (0: geen limiet)",
|
"The rate limit must be a non-negative number (0: no limit)": "De snelheidslimiet moet een positief nummer zijn (0: geen limiet)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "De scanfrequentie moet een positief getal in seconden zijn.",
|
"The rescan interval must be a non-negative number of seconds.": "De scanfrequentie moet een positief getal in seconden zijn.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Het wordt automatisch opnieuw geprobeerd. Bestanden worden gesynchroniseerd als de fout is hersteld.",
|
"They are retried automatically and will be synced when the error is resolved.": "Het wordt automatisch opnieuw geprobeerd. Bestanden worden gesynchroniseerd als de fout is hersteld.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Dit kan kwaadwilligen eenvoudig toegang geven tot het lezen en wijzigen van bestanden op jouw computer.",
|
"This can easily give hackers access to read and change any files on your computer.": "Dit kan kwaadwilligen eenvoudig toegang geven tot het lezen en wijzigen van bestanden op jouw computer.",
|
||||||
"This is a major version upgrade.": "Dit is een grote update.",
|
"This is a major version upgrade.": "Dit is een grote update.",
|
||||||
"Trash Can File Versioning": "Versiebeheer bestanden prullenbak",
|
"Trash Can File Versioning": "Versiebeheer bestanden prullenbak",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Versie",
|
"Version": "Versie",
|
||||||
"Versions Path": "Bestandspad versies",
|
"Versions Path": "Bestandspad versies",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versies worden automatisch verwijderd als deze ouder zijn dan de maximale leeftijd of als ze het maximaal aantal toegestane bestanden per interval overschrijden. ",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versies worden automatisch verwijderd als deze ouder zijn dan de maximale leeftijd of als ze het maximaal aantal toegestane bestanden per interval overschrijden. ",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Wanneer een nieuw toestel wordt toegevoegd, houd er dan rekening mee dat dit toestel ook aan de andere kant moet worden toegevoegd.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Wanneer een nieuw toestel wordt toegevoegd, houd er dan rekening mee dat dit toestel ook aan de andere kant moet worden toegevoegd.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Houd er bij het toevoegen van nieuwe mappen rekening mee dat het map-ID gebruikt wordt om mappen tussen apparaten te verbinden. Dit ID is hoofdlettergevoelig en moet identiek zijn op andere apparaten.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Houd er bij het toevoegen van nieuwe mappen rekening mee dat het map-ID gebruikt wordt om mappen tussen apparaten te verbinden. Dit ID is hoofdlettergevoelig en moet identiek zijn op andere apparaten.",
|
||||||
"Yes": "Ja",
|
"Yes": "Ja",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "dagen",
|
"days": "dagen",
|
||||||
"full documentation": "volledige documentatie",
|
"full documentation": "volledige documentatie",
|
||||||
"items": "objecten",
|
"items": "objecten",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} wil de map \"{{folder}}\" delen."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} wil de map \"{{folder}}\" delen.",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Legg til",
|
"Add": "Legg til",
|
||||||
"Add Device": "Legg Til Eining",
|
"Add Device": "Legg Til Eining",
|
||||||
"Add Folder": "Legg Til Mappe",
|
"Add Folder": "Legg Til Mappe",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Leggja til ny mappe?",
|
"Add new folder?": "Leggja til ny mappe?",
|
||||||
"Address": "Adresse",
|
"Address": "Adresse",
|
||||||
"Addresses": "Adresser",
|
"Addresses": "Adresser",
|
||||||
"Advanced": "Avansert",
|
"Advanced": "Avansert",
|
||||||
"Advanced Configuration": "Avansert konfigurasjon",
|
"Advanced Configuration": "Avansert konfigurasjon",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Alle data",
|
"All Data": "Alle data",
|
||||||
"Allow Anonymous Usage Reporting?": "Tillata anonymisert bruksrapportering?",
|
"Allow Anonymous Usage Reporting?": "Tillata anonymisert bruksrapportering?",
|
||||||
"Alphabetic": "Alfabetisk",
|
"Alphabetic": "Alfabetisk",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Tilkoplingsfeil",
|
"Connection Error": "Tilkoplingsfeil",
|
||||||
"Copied from elsewhere": "Kopiert frå ein annan stad",
|
"Copied from elsewhere": "Kopiert frå ein annan stad",
|
||||||
"Copied from original": "Kopiert frå originalen",
|
"Copied from original": "Kopiert frå originalen",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Opphavsrett © 2015 og desse bidragsytarane:",
|
"Copyright © 2015 the following Contributors:": "Opphavsrett © 2015 og desse bidragsytarane:",
|
||||||
"Danger!": "Fare!",
|
"Danger!": "Fare!",
|
||||||
"Delete": "Slett",
|
"Delete": "Slett",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Filer er beskytta mot endringar gjort på andre einingar, men endringar gjort på denne eininga vert sende til resten av klyngja.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Filer er beskytta mot endringar gjort på andre einingar, men endringar gjort på denne eininga vert sende til resten av klyngja.",
|
||||||
"Folder": "Mappe",
|
"Folder": "Mappe",
|
||||||
"Folder ID": "Mappe ID",
|
"Folder ID": "Mappe ID",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Styrande Mappe",
|
"Folder Master": "Styrande Mappe",
|
||||||
"Folder Path": "Mappeplassering",
|
"Folder Path": "Mappeplassering",
|
||||||
"Folders": "Mapper",
|
"Folders": "Mapper",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Av",
|
"Off": "Av",
|
||||||
"Oldest First": "Elste fyrst",
|
"Oldest First": "Elste fyrst",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Val",
|
"Options": "Val",
|
||||||
"Out of Sync": "Ikkje synkronisert",
|
"Out of Sync": "Ikkje synkronisert",
|
||||||
"Out of Sync Items": "Ikkje-synkroniserte element",
|
"Out of Sync Items": "Ikkje-synkroniserte element",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Relé via",
|
"Relayed via": "Relé via",
|
||||||
"Relays": "Reléer",
|
"Relays": "Reléer",
|
||||||
"Release Notes": "Utgivingsnotat",
|
"Release Notes": "Utgivingsnotat",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Fjern",
|
"Remove": "Fjern",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Skann På Ny",
|
"Rescan": "Skann På Ny",
|
||||||
"Rescan All": "Skann alle på nytt",
|
"Rescan All": "Skann alle på nytt",
|
||||||
"Rescan Interval": "Skanneintervall",
|
"Rescan Interval": "Skanneintervall",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "Hastigheitsgrensa må ver eit positivt tall (0: ingen grensa)",
|
"The rate limit must be a non-negative number (0: no limit)": "Hastigheitsgrensa må ver eit positivt tall (0: ingen grensa)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Talet på sekund i skanneintervallet kan ikkje vera negativt.",
|
"The rescan interval must be a non-negative number of seconds.": "Talet på sekund i skanneintervallet kan ikkje vera negativt.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Desse vil bli prøvd på nytt automatisk og vil bli synkronisert når feilen har blitt utbetra.",
|
"They are retried automatically and will be synced when the error is resolved.": "Desse vil bli prøvd på nytt automatisk og vil bli synkronisert når feilen har blitt utbetra.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Dette kan lett gje dataekspertar tilgang til å lese og endre vilkårlege filer på denne maskina.",
|
"This can easily give hackers access to read and change any files on your computer.": "Dette kan lett gje dataekspertar tilgang til å lese og endre vilkårlege filer på denne maskina.",
|
||||||
"This is a major version upgrade.": "Dette er ei hovudoppgradering",
|
"This is a major version upgrade.": "Dette er ei hovudoppgradering",
|
||||||
"Trash Can File Versioning": "Papirkorg filutgåvehandtering",
|
"Trash Can File Versioning": "Papirkorg filutgåvehandtering",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Versjon",
|
"Version": "Versjon",
|
||||||
"Versions Path": "Utgåvebane",
|
"Versions Path": "Utgåvebane",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Utgåver vert automatisk sletta når maksimal levetid er nådd eller når det høgaste tillate talet på filer innan eit intervall vert overskride.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Utgåver vert automatisk sletta når maksimal levetid er nådd eller når det høgaste tillate talet på filer innan eit intervall vert overskride.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Hugs at når ei ny eining vert lagt til må ho òg leggjast til på andre sida.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Hugs at når ei ny eining vert lagt til må ho òg leggjast til på andre sida.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Hugs at når ei ny mappe vert lagt til, vert mappe-ID-en brukt til å binda saman mappene mellom einingane. Det er skilnad på store og små bokstavar, så ID-ane må vera identiske på alle einingane.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Hugs at når ei ny mappe vert lagt til, vert mappe-ID-en brukt til å binda saman mappene mellom einingane. Det er skilnad på store og små bokstavar, så ID-ane må vera identiske på alle einingane.",
|
||||||
"Yes": "Ja",
|
"Yes": "Ja",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "dagar",
|
"days": "dagar",
|
||||||
"full documentation": "all dokumentasjon",
|
"full documentation": "all dokumentasjon",
|
||||||
"items": "element",
|
"items": "element",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} ønskjer å dela mappa \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} ønskjer å dela mappa \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"A device with that ID is already added.": "A device with that ID is already added.",
|
"A device with that ID is already added.": "Urządzenie o tym ID jest już dodane.",
|
||||||
"A negative number of days doesn't make sense.": "Ujemna ilość dni nie ma sensu.",
|
"A negative number of days doesn't make sense.": "Ujemna ilość dni nie ma sensu.",
|
||||||
"A new major version may not be compatible with previous versions.": "Nowa wersja może być niekompatybilna z poprzednimi wersjami.",
|
"A new major version may not be compatible with previous versions.": "Nowa wersja może być niekompatybilna z poprzednimi wersjami.",
|
||||||
"API Key": "Klucz API",
|
"API Key": "Klucz API",
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Dodaj",
|
"Add": "Dodaj",
|
||||||
"Add Device": "Dodaj urządzenie",
|
"Add Device": "Dodaj urządzenie",
|
||||||
"Add Folder": "Dodaj folder",
|
"Add Folder": "Dodaj folder",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Dodać nowy folder?",
|
"Add new folder?": "Dodać nowy folder?",
|
||||||
"Address": "Adres",
|
"Address": "Adres",
|
||||||
"Addresses": "Adresy",
|
"Addresses": "Adresy",
|
||||||
"Advanced": "Zaawansowane",
|
"Advanced": "Zaawansowane",
|
||||||
"Advanced Configuration": "Konfiguracja zaawansowana",
|
"Advanced Configuration": "Konfiguracja zaawansowana",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Wszystkie dane",
|
"All Data": "Wszystkie dane",
|
||||||
"Allow Anonymous Usage Reporting?": "Zezwalaj na anonimowe statystyki użycia?",
|
"Allow Anonymous Usage Reporting?": "Zezwalaj na anonimowe statystyki użycia?",
|
||||||
"Alphabetic": "Alfabetycznie",
|
"Alphabetic": "Alfabetycznie",
|
||||||
@@ -32,8 +34,9 @@
|
|||||||
"Connection Error": "Błąd połączenia",
|
"Connection Error": "Błąd połączenia",
|
||||||
"Copied from elsewhere": "Skopiowane z innego miejsca ",
|
"Copied from elsewhere": "Skopiowane z innego miejsca ",
|
||||||
"Copied from original": "Skopiowane z oryginału",
|
"Copied from original": "Skopiowane z oryginału",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015: ",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015: ",
|
||||||
"Danger!": "Danger!",
|
"Danger!": "Niebezpieczne!",
|
||||||
"Delete": "Usuń",
|
"Delete": "Usuń",
|
||||||
"Deleted": "Usunięto",
|
"Deleted": "Usunięto",
|
||||||
"Device ID": "ID urządzenia",
|
"Device ID": "ID urządzenia",
|
||||||
@@ -51,7 +54,7 @@
|
|||||||
"Edit Device": "Edytuj urządzenie",
|
"Edit Device": "Edytuj urządzenie",
|
||||||
"Edit Folder": "Edytuj folder",
|
"Edit Folder": "Edytuj folder",
|
||||||
"Editing": "Edytowanie",
|
"Editing": "Edytowanie",
|
||||||
"Enable Relaying": "Enable Relaying",
|
"Enable Relaying": "Włącz przekazywanie",
|
||||||
"Enable UPnP": "Włącz UPnP",
|
"Enable UPnP": "Włącz UPnP",
|
||||||
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Wpisz oddzielone przecinkiem adresy (\"tcp://ip:port\", \"tcp://host:port\") lub \"dynamic\" by przeprowadzić automatyczne odnalezienie adresu.",
|
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Wpisz oddzielone przecinkiem adresy (\"tcp://ip:port\", \"tcp://host:port\") lub \"dynamic\" by przeprowadzić automatyczne odnalezienie adresu.",
|
||||||
"Enter ignore patterns, one per line.": "Wprowadź wzorce ignorowania, jeden w każdej linii.",
|
"Enter ignore patterns, one per line.": "Wprowadź wzorce ignorowania, jeden w każdej linii.",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Pliki są zabezpieczone przed zmianami na innym urządzeniu, jednak zmiany w tym urządzeniu będą wysłane do reszty.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Pliki są zabezpieczone przed zmianami na innym urządzeniu, jednak zmiany w tym urządzeniu będą wysłane do reszty.",
|
||||||
"Folder": "Folder",
|
"Folder": "Folder",
|
||||||
"Folder ID": "ID folderu",
|
"Folder ID": "ID folderu",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Główny folder",
|
"Folder Master": "Główny folder",
|
||||||
"Folder Path": "Ścieżka folderu",
|
"Folder Path": "Ścieżka folderu",
|
||||||
"Folders": "Foldery",
|
"Folders": "Foldery",
|
||||||
@@ -76,7 +80,7 @@
|
|||||||
"Generate": "Generuj",
|
"Generate": "Generuj",
|
||||||
"Global Discovery": "Globalne odnajdywanie",
|
"Global Discovery": "Globalne odnajdywanie",
|
||||||
"Global Discovery Server": "Globalny serwer rozgłoszeniowy",
|
"Global Discovery Server": "Globalny serwer rozgłoszeniowy",
|
||||||
"Global Discovery Servers": "Global Discovery Servers",
|
"Global Discovery Servers": "Globalne serwery odkrywania",
|
||||||
"Global State": "Status globalny",
|
"Global State": "Status globalny",
|
||||||
"Help": "Pomoc",
|
"Help": "Pomoc",
|
||||||
"Home page": "Strona domowa",
|
"Home page": "Strona domowa",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Wyłącz",
|
"Off": "Wyłącz",
|
||||||
"Oldest First": "Najstarsze na początku",
|
"Oldest First": "Najstarsze na początku",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Opcje",
|
"Options": "Opcje",
|
||||||
"Out of Sync": "Niezsynchronizowane",
|
"Out of Sync": "Niezsynchronizowane",
|
||||||
"Out of Sync Items": "Niezsynchronizowane pliki",
|
"Out of Sync Items": "Niezsynchronizowane pliki",
|
||||||
@@ -121,18 +126,20 @@
|
|||||||
"Pause": "Zatrzymaj",
|
"Pause": "Zatrzymaj",
|
||||||
"Paused": "Zatrzymany",
|
"Paused": "Zatrzymany",
|
||||||
"Please consult the release notes before performing a major upgrade.": "Zaleca się przeanalizowanie \"release notes\" przed przeprowadzeniem znaczącej aktualizacji.",
|
"Please consult the release notes before performing a major upgrade.": "Zaleca się przeanalizowanie \"release notes\" przed przeprowadzeniem znaczącej aktualizacji.",
|
||||||
"Please set a GUI Authentication User and Password in the Settings dialog.": "Please set a GUI Authentication User and Password in the Settings dialog.",
|
"Please set a GUI Authentication User and Password in the Settings dialog.": "Ustaw proszę użytkownika i hasło dostępowe do GUI w Ustawieniach",
|
||||||
"Please wait": "Proszę czekać",
|
"Please wait": "Proszę czekać",
|
||||||
"Preview": "Podgląd",
|
"Preview": "Podgląd",
|
||||||
"Preview Usage Report": "Podgląd raportu użycia.",
|
"Preview Usage Report": "Podgląd raportu użycia.",
|
||||||
"Quick guide to supported patterns": "Krótki przewodnik po obsługiwanych wzorcach",
|
"Quick guide to supported patterns": "Krótki przewodnik po obsługiwanych wzorcach",
|
||||||
"RAM Utilization": "Użycie pamięci RAM",
|
"RAM Utilization": "Użycie pamięci RAM",
|
||||||
"Random": "Losowo",
|
"Random": "Losowo",
|
||||||
"Relay Servers": "Relay Servers",
|
"Relay Servers": "Serwery przekazywania",
|
||||||
"Relayed via": "Przekazane przez",
|
"Relayed via": "Przekazane przez",
|
||||||
"Relays": "Przekaźniki",
|
"Relays": "Przekaźniki",
|
||||||
"Release Notes": "Informacje o wydaniu",
|
"Release Notes": "Informacje o wydaniu",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Usuń",
|
"Remove": "Usuń",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Skanuj ponownie",
|
"Rescan": "Skanuj ponownie",
|
||||||
"Rescan All": "Skanuj wszystko ponownie",
|
"Rescan All": "Skanuj wszystko ponownie",
|
||||||
"Rescan Interval": "Interwał skanowania",
|
"Rescan Interval": "Interwał skanowania",
|
||||||
@@ -142,7 +149,7 @@
|
|||||||
"Resume": "Wznów",
|
"Resume": "Wznów",
|
||||||
"Reused": "Ponownie użyte",
|
"Reused": "Ponownie użyte",
|
||||||
"Save": "Zapisz",
|
"Save": "Zapisz",
|
||||||
"Scan Time Remaining": "Scan Time Remaining",
|
"Scan Time Remaining": "Pozostały czas skanowania",
|
||||||
"Scanning": "Skanowanie",
|
"Scanning": "Skanowanie",
|
||||||
"Select the devices to share this folder with.": "Wybierz urządzenie, któremu udostępnić folder.",
|
"Select the devices to share this folder with.": "Wybierz urządzenie, któremu udostępnić folder.",
|
||||||
"Select the folders to share with this device.": "Wybierz foldery do współdzielenia z tym urządzeniem.",
|
"Select the folders to share with this device.": "Wybierz foldery do współdzielenia z tym urządzeniem.",
|
||||||
@@ -155,7 +162,7 @@
|
|||||||
"Shared With": "Współdzielony z",
|
"Shared With": "Współdzielony z",
|
||||||
"Short identifier for the folder. Must be the same on all cluster devices.": "Krótki identyfikator folderu. Musi być taki sam na wszystkich urządzeniach.",
|
"Short identifier for the folder. Must be the same on all cluster devices.": "Krótki identyfikator folderu. Musi być taki sam na wszystkich urządzeniach.",
|
||||||
"Show ID": "Pokaż ID",
|
"Show ID": "Pokaż ID",
|
||||||
"Show QR": "Show QR",
|
"Show QR": "Pokaż kod QR",
|
||||||
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Pokazane w statusie zamiast ID urządzenia.Zostanie wysłane do innych urządzeń jako opcjonalna domyślna nazwa.",
|
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Pokazane w statusie zamiast ID urządzenia.Zostanie wysłane do innych urządzeń jako opcjonalna domyślna nazwa.",
|
||||||
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Pokazane w statusie zamiast ID urządzenia. Zostanie zaktualizowane do nazwy urządzenia jeżeli pozostanie puste.",
|
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Pokazane w statusie zamiast ID urządzenia. Zostanie zaktualizowane do nazwy urządzenia jeżeli pozostanie puste.",
|
||||||
"Shutdown": "Wyłącz",
|
"Shutdown": "Wyłącz",
|
||||||
@@ -177,11 +184,11 @@
|
|||||||
"Syncthing is upgrading.": "Aktualizowanie Syncthing",
|
"Syncthing is upgrading.": "Aktualizowanie Syncthing",
|
||||||
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing wydaje się być wyłączony lub jest problem z twoim połączeniem internetowym. Próbuje ponownie...",
|
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing wydaje się być wyłączony lub jest problem z twoim połączeniem internetowym. Próbuje ponownie...",
|
||||||
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing nie może przetworzyć twojego zapytania. Proszę przeładuj stronę lub zrestartuj Syncthing, jeśli problem pozostanie.",
|
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing nie może przetworzyć twojego zapytania. Proszę przeładuj stronę lub zrestartuj Syncthing, jeśli problem pozostanie.",
|
||||||
"The Syncthing admin interface is configured to allow remote access without a password.": "The Syncthing admin interface is configured to allow remote access without a password.",
|
"The Syncthing admin interface is configured to allow remote access without a password.": "Interfejs administracyjny Syncthing jest skonfigurowany w sposób pozwalający na zdalny dostęp bez hasła.",
|
||||||
"The aggregated statistics are publicly available at {%url%}.": "Zebrane statystyki są publicznie dostępne pod adresem {{url}}.",
|
"The aggregated statistics are publicly available at {%url%}.": "Zebrane statystyki są publicznie dostępne pod adresem {{url}}.",
|
||||||
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Konfiguracja została zapisana lecz nie jest aktywna. Syncthing musi zostać zrestartowany aby aktywować nową konfiguracje.",
|
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Konfiguracja została zapisana lecz nie jest aktywna. Syncthing musi zostać zrestartowany aby aktywować nową konfiguracje.",
|
||||||
"The device ID cannot be blank.": "ID urządzenia nie może być puste.",
|
"The device ID cannot be blank.": "ID urządzenia nie może być puste.",
|
||||||
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).",
|
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "ID urządzenia może być znalezione w \"Akcja > Pokaż ID\" na innym urządzeniu. Spacje i myślniki są opcjonalne (są one ignorowane).",
|
||||||
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "ID urządzenia można znaleźć w \"Edytuj -> Pokaż ID\" na zdalnym urządzeniu.\nOdstępy i myślniki są opcjonalne (ignorowane)",
|
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "ID urządzenia można znaleźć w \"Edytuj -> Pokaż ID\" na zdalnym urządzeniu.\nOdstępy i myślniki są opcjonalne (ignorowane)",
|
||||||
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "Zaszyfrowane raporty użycia są wysyłane codziennie. Są one używane w celach statystycznych platform, rozmiarów katalogów i wersji programu. Jeżeli zgłaszane dane ulegną zmianie, ponownie wyświetli się ta informacja.",
|
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "Zaszyfrowane raporty użycia są wysyłane codziennie. Są one używane w celach statystycznych platform, rozmiarów katalogów i wersji programu. Jeżeli zgłaszane dane ulegną zmianie, ponownie wyświetli się ta informacja.",
|
||||||
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "Wprowadzone ID urządzenia wygląda na niepoprawne. Musi zawierać 52 lub 56 znaków składających się z liter i cyfr. Odstępy i myślniki są opcjonalne.",
|
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "Wprowadzone ID urządzenia wygląda na niepoprawne. Musi zawierać 52 lub 56 znaków składających się z liter i cyfr. Odstępy i myślniki są opcjonalne.",
|
||||||
@@ -203,7 +210,8 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "Ograniczenie prędkości powinno być nieujemną liczbą całkowitą (0: brak ograniczeń)",
|
"The rate limit must be a non-negative number (0: no limit)": "Ograniczenie prędkości powinno być nieujemną liczbą całkowitą (0: brak ograniczeń)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Interwał skanowania musi być niezerową liczbą sekund.",
|
"The rescan interval must be a non-negative number of seconds.": "Interwał skanowania musi być niezerową liczbą sekund.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Ponowne próby zachodzą automatycznie, synchronizacja nastąpi po usunięciu usterki.",
|
"They are retried automatically and will be synced when the error is resolved.": "Ponowne próby zachodzą automatycznie, synchronizacja nastąpi po usunięciu usterki.",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
"This Device": "This Device",
|
||||||
|
"This can easily give hackers access to read and change any files on your computer.": "Może to umożliwić osobom trzecim dostęp do odczytu i zmian dowolnych plików na urządzeniu.",
|
||||||
"This is a major version upgrade.": "To jest ważna aktualizacja",
|
"This is a major version upgrade.": "To jest ważna aktualizacja",
|
||||||
"Trash Can File Versioning": "Kontrola werjsi plików w koszu",
|
"Trash Can File Versioning": "Kontrola werjsi plików w koszu",
|
||||||
"Unknown": "Nieznany",
|
"Unknown": "Nieznany",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Wersja",
|
"Version": "Wersja",
|
||||||
"Versions Path": "Ścieżka wersji",
|
"Versions Path": "Ścieżka wersji",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Wersje zostają automatycznie usunięte jeżeli są starsze niż maksymalny wiek lub przekraczają liczbę dopuszczalnych wersji.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Wersje zostają automatycznie usunięte jeżeli są starsze niż maksymalny wiek lub przekraczają liczbę dopuszczalnych wersji.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Gdy dodajesz nowe urządzenie, pamiętaj że urządzenie musi zostać dodane także po drugiej stronie.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Gdy dodajesz nowe urządzenie, pamiętaj że urządzenie musi zostać dodane także po drugiej stronie.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Przy dodawaniu nowego folderu, pamiętaj, że ID użyte jest do łączenia folderów pomiędzy urządzeniami. Wielkość liter ciągu ma znaczenie musi zgadzać się na wszystkich urządzeniach.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Przy dodawaniu nowego folderu, pamiętaj, że ID użyte jest do łączenia folderów pomiędzy urządzeniami. Wielkość liter ciągu ma znaczenie musi zgadzać się na wszystkich urządzeniach.",
|
||||||
"Yes": "Tak",
|
"Yes": "Tak",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "dni",
|
"days": "dni",
|
||||||
"full documentation": "pełna dokumentacja",
|
"full documentation": "pełna dokumentacja",
|
||||||
"items": "pozycji",
|
"items": "pozycji",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} chce udostępnić folder \"{{folder}}\""
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} chce udostępnić folder \"{{folder}}\"",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Adicionar",
|
"Add": "Adicionar",
|
||||||
"Add Device": "Adicionar dispositivo",
|
"Add Device": "Adicionar dispositivo",
|
||||||
"Add Folder": "Adicionar pasta",
|
"Add Folder": "Adicionar pasta",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Adicionar nova pasta?",
|
"Add new folder?": "Adicionar nova pasta?",
|
||||||
"Address": "Endereço",
|
"Address": "Endereço",
|
||||||
"Addresses": "Endereços",
|
"Addresses": "Endereços",
|
||||||
"Advanced": "Avançado",
|
"Advanced": "Avançado",
|
||||||
"Advanced Configuration": "Configuração avançada",
|
"Advanced Configuration": "Configuração avançada",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Todos os dados",
|
"All Data": "Todos os dados",
|
||||||
"Allow Anonymous Usage Reporting?": "Permitir envio de relatórios anônimos de uso?",
|
"Allow Anonymous Usage Reporting?": "Permitir envio de relatórios anônimos de uso?",
|
||||||
"Alphabetic": "Alfabética",
|
"Alphabetic": "Alfabética",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Erro de conexão",
|
"Connection Error": "Erro de conexão",
|
||||||
"Copied from elsewhere": "Copiado de outro lugar",
|
"Copied from elsewhere": "Copiado de outro lugar",
|
||||||
"Copied from original": "Copiado do original",
|
"Copied from original": "Copiado do original",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015. Direitos reservados aos seguintes colaboradores:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015. Direitos reservados aos seguintes colaboradores:",
|
||||||
"Danger!": "Perigo!",
|
"Danger!": "Perigo!",
|
||||||
"Delete": "Apagar",
|
"Delete": "Apagar",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Os arquivos estão protegidos contra alterações feitas em outros dispositivos, mas alterações feitas neste dispositivo serão enviadas ao resto dos dispositivos.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Os arquivos estão protegidos contra alterações feitas em outros dispositivos, mas alterações feitas neste dispositivo serão enviadas ao resto dos dispositivos.",
|
||||||
"Folder": "Pasta",
|
"Folder": "Pasta",
|
||||||
"Folder ID": "ID da pasta",
|
"Folder ID": "ID da pasta",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Pasta mestre",
|
"Folder Master": "Pasta mestre",
|
||||||
"Folder Path": "Caminho da pasta",
|
"Folder Path": "Caminho da pasta",
|
||||||
"Folders": "Pastas",
|
"Folders": "Pastas",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Desligada",
|
"Off": "Desligada",
|
||||||
"Oldest First": "Mais antigo primeiro",
|
"Oldest First": "Mais antigo primeiro",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Opções",
|
"Options": "Opções",
|
||||||
"Out of Sync": "Fora de sincronia",
|
"Out of Sync": "Fora de sincronia",
|
||||||
"Out of Sync Items": "Fora de sincronia",
|
"Out of Sync Items": "Fora de sincronia",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Retransmitido via",
|
"Relayed via": "Retransmitido via",
|
||||||
"Relays": "Retransmissores",
|
"Relays": "Retransmissores",
|
||||||
"Release Notes": "Notas de lançamento",
|
"Release Notes": "Notas de lançamento",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Remover",
|
"Remove": "Remover",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Verificar agora",
|
"Rescan": "Verificar agora",
|
||||||
"Rescan All": "Verificar todas",
|
"Rescan All": "Verificar todas",
|
||||||
"Rescan Interval": "Intervalo entre verificações",
|
"Rescan Interval": "Intervalo entre verificações",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "O limite de velocidade deve ser um número positivo (0: sem limite)",
|
"The rate limit must be a non-negative number (0: no limit)": "O limite de velocidade deve ser um número positivo (0: sem limite)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "O intervalo entre verificações deve ser um número positivo de segundos.",
|
"The rescan interval must be a non-negative number of seconds.": "O intervalo entre verificações deve ser um número positivo de segundos.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Serão tentadas automaticamente e sincronizadas após o erro ter sido resolvido.",
|
"They are retried automatically and will be synced when the error is resolved.": "Serão tentadas automaticamente e sincronizadas após o erro ter sido resolvido.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Isto pode dar a hackers poder de leitura e escrita de qualquer arquivo em seu dispositivo.",
|
"This can easily give hackers access to read and change any files on your computer.": "Isto pode dar a hackers poder de leitura e escrita de qualquer arquivo em seu dispositivo.",
|
||||||
"This is a major version upgrade.": "Esta é uma atualização para uma versão \"major\".",
|
"This is a major version upgrade.": "Esta é uma atualização para uma versão \"major\".",
|
||||||
"Trash Can File Versioning": "Versionamento de arquivos da lixeira",
|
"Trash Can File Versioning": "Versionamento de arquivos da lixeira",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Versão",
|
"Version": "Versão",
|
||||||
"Versions Path": "Caminho das versões",
|
"Versions Path": "Caminho das versões",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "As versões são automaticamente apagadas se elas são mais antigas do que a idade máxima ou excederem o número de arquivos permitido em um intervalo.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "As versões são automaticamente apagadas se elas são mais antigas do que a idade máxima ou excederem o número de arquivos permitido em um intervalo.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Quando estiver adicionando um dispositivo, lembre-se de que este dispositivo deve ser adicionado do outro lado também.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Quando estiver adicionando um dispositivo, lembre-se de que este dispositivo deve ser adicionado do outro lado também.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Quando adicionar uma nova pasta, lembre-se que o ID da pasta é utilizado para ligar pastas entre dispositivos. Ele é sensível às diferenças entre maiúsculas e minúsculas e deve ser o mesmo em todos os dispositivos.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Quando adicionar uma nova pasta, lembre-se que o ID da pasta é utilizado para ligar pastas entre dispositivos. Ele é sensível às diferenças entre maiúsculas e minúsculas e deve ser o mesmo em todos os dispositivos.",
|
||||||
"Yes": "Sim",
|
"Yes": "Sim",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "dias",
|
"days": "dias",
|
||||||
"full documentation": "documentação completa",
|
"full documentation": "documentação completa",
|
||||||
"items": "itens",
|
"items": "itens",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} quer compartilhar a pasta \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} quer compartilhar a pasta \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Adicionar",
|
"Add": "Adicionar",
|
||||||
"Add Device": "Adicionar dispositivo",
|
"Add Device": "Adicionar dispositivo",
|
||||||
"Add Folder": "Adicionar pasta",
|
"Add Folder": "Adicionar pasta",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Adicionar nova pasta?",
|
"Add new folder?": "Adicionar nova pasta?",
|
||||||
"Address": "Endereço",
|
"Address": "Endereço",
|
||||||
"Addresses": "Endereços",
|
"Addresses": "Endereços",
|
||||||
"Advanced": "Avançadas",
|
"Advanced": "Avançadas",
|
||||||
"Advanced Configuration": "Configuração avançada",
|
"Advanced Configuration": "Configuração avançada",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Todos os dados",
|
"All Data": "Todos os dados",
|
||||||
"Allow Anonymous Usage Reporting?": "Permitir envio de relatórios anónimos de utilização?",
|
"Allow Anonymous Usage Reporting?": "Permitir envio de relatórios anónimos de utilização?",
|
||||||
"Alphabetic": "Alfabética",
|
"Alphabetic": "Alfabética",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Erro de ligação",
|
"Connection Error": "Erro de ligação",
|
||||||
"Copied from elsewhere": "Copiado doutro sítio",
|
"Copied from elsewhere": "Copiado doutro sítio",
|
||||||
"Copied from original": "Copiado do original",
|
"Copied from original": "Copiado do original",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 os seguintes contribuidores:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 os seguintes contribuidores:",
|
||||||
"Danger!": "Perigo!",
|
"Danger!": "Perigo!",
|
||||||
"Delete": "Eliminar",
|
"Delete": "Eliminar",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Os ficheiros estão protegidos contra alterações feitas noutros dispositivos, mas alterações feitas neste dispositivo serão enviadas ao resto do grupo.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Os ficheiros estão protegidos contra alterações feitas noutros dispositivos, mas alterações feitas neste dispositivo serão enviadas ao resto do grupo.",
|
||||||
"Folder": "Pasta",
|
"Folder": "Pasta",
|
||||||
"Folder ID": "ID da pasta",
|
"Folder ID": "ID da pasta",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Pasta mestre",
|
"Folder Master": "Pasta mestre",
|
||||||
"Folder Path": "Caminho da pasta",
|
"Folder Path": "Caminho da pasta",
|
||||||
"Folders": "Pastas",
|
"Folders": "Pastas",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Desligada",
|
"Off": "Desligada",
|
||||||
"Oldest First": "Primeiro os mais antigos",
|
"Oldest First": "Primeiro os mais antigos",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Opções",
|
"Options": "Opções",
|
||||||
"Out of Sync": "Fora de sincronia",
|
"Out of Sync": "Fora de sincronia",
|
||||||
"Out of Sync Items": "Itens por sincronizar",
|
"Out of Sync Items": "Itens por sincronizar",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Retransmitido via",
|
"Relayed via": "Retransmitido via",
|
||||||
"Relays": "Retransmissores",
|
"Relays": "Retransmissores",
|
||||||
"Release Notes": "Notas de lançamento",
|
"Release Notes": "Notas de lançamento",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Remover",
|
"Remove": "Remover",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Verificar agora",
|
"Rescan": "Verificar agora",
|
||||||
"Rescan All": "Verificar todas agora",
|
"Rescan All": "Verificar todas agora",
|
||||||
"Rescan Interval": "Intervalo entre verificações",
|
"Rescan Interval": "Intervalo entre verificações",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "O limite de velocidade tem que ser um número que não seja negativo (0: sem limite)",
|
"The rate limit must be a non-negative number (0: no limit)": "O limite de velocidade tem que ser um número que não seja negativo (0: sem limite)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "O intervalo entre verificações tem que ser um valor não negativo de segundos.",
|
"The rescan interval must be a non-negative number of seconds.": "O intervalo entre verificações tem que ser um valor não negativo de segundos.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Será tentado automaticamente e os itens serão sincronizados assim que o erro seja resolvido.",
|
"They are retried automatically and will be synced when the error is resolved.": "Será tentado automaticamente e os itens serão sincronizados assim que o erro seja resolvido.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Isso facilmente dará acesso aos piratas informáticos para lerem e modificarem quaisquer ficheiros no seu computador.",
|
"This can easily give hackers access to read and change any files on your computer.": "Isso facilmente dará acesso aos piratas informáticos para lerem e modificarem quaisquer ficheiros no seu computador.",
|
||||||
"This is a major version upgrade.": "Esta é uma actualização para uma versão importante.",
|
"This is a major version upgrade.": "Esta é uma actualização para uma versão importante.",
|
||||||
"Trash Can File Versioning": "Reciclagem",
|
"Trash Can File Versioning": "Reciclagem",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Versão",
|
"Version": "Versão",
|
||||||
"Versions Path": "Caminho das versões",
|
"Versions Path": "Caminho das versões",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "As versões são eliminadas automaticamente se forem mais antigas do que a idade máxima ou excederem o número máximo de ficheiros permitido num intervalo.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "As versões são eliminadas automaticamente se forem mais antigas do que a idade máxima ou excederem o número máximo de ficheiros permitido num intervalo.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Quando adicionar um novo dispositivo, lembre-se que este dispositivo tem que ser adicionado do outro lado também.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Quando adicionar um novo dispositivo, lembre-se que este dispositivo tem que ser adicionado do outro lado também.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Quando adicionar uma nova pasta, lembre-se que o ID da pasta é utilizado para ligar as pastas entre dispositivos. É sensível às diferenças entre maiúsculas e minúsculas e tem que ter uma correspondência perfeita entre todos os dispositivos.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Quando adicionar uma nova pasta, lembre-se que o ID da pasta é utilizado para ligar as pastas entre dispositivos. É sensível às diferenças entre maiúsculas e minúsculas e tem que ter uma correspondência perfeita entre todos os dispositivos.",
|
||||||
"Yes": "Sim",
|
"Yes": "Sim",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "dias",
|
"days": "dias",
|
||||||
"full documentation": "documentação completa",
|
"full documentation": "documentação completa",
|
||||||
"items": "itens",
|
"items": "itens",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} quer partilhar a pasta \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} quer partilhar a pasta \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -1,231 +0,0 @@
|
|||||||
{
|
|
||||||
"A device with that ID is already added.": "A device with that ID is already added.",
|
|
||||||
"A negative number of days doesn't make sense.": "A negative number of days doesn't make sense.",
|
|
||||||
"A new major version may not be compatible with previous versions.": "A new major version may not be compatible with previous versions.",
|
|
||||||
"API Key": "Cheie API",
|
|
||||||
"About": "Despre",
|
|
||||||
"Actions": "Actions",
|
|
||||||
"Add": "Adaugă",
|
|
||||||
"Add Device": "Adaugă Dispozitiv",
|
|
||||||
"Add Folder": "Adaugă Mapă",
|
|
||||||
"Add new folder?": "Adauga o mapă nouă?",
|
|
||||||
"Address": "Adresă",
|
|
||||||
"Addresses": "Adrese",
|
|
||||||
"Advanced": "Advanced",
|
|
||||||
"Advanced Configuration": "Configurari avansate",
|
|
||||||
"All Data": "Toate Datele",
|
|
||||||
"Allow Anonymous Usage Reporting?": "Permiteţi raportarea anonimă de folosire a aplicaţiei?",
|
|
||||||
"Alphabetic": "Alphabetic",
|
|
||||||
"An external command handles the versioning. It has to remove the file from the synced folder.": "O comandă externă administrează versiunile. Trebuie să şteargă documentul din fişierul sincronizat. ",
|
|
||||||
"Anonymous Usage Reporting": "Raport Anonim despre Folosirea Aplicației",
|
|
||||||
"Any devices configured on an introducer device will be added to this device as well.": "Toate dispozitivele configurate pe un dispozitiv iniţiator vor fi adăugate şi pe acest dispozitiv. ",
|
|
||||||
"Automatic upgrades": "Actualizare automată",
|
|
||||||
"Be careful!": "Fii atent!",
|
|
||||||
"Bugs": "Bug-uri",
|
|
||||||
"CPU Utilization": "CPU ",
|
|
||||||
"Changelog": "Noutăți",
|
|
||||||
"Clean out after": "Clean out after",
|
|
||||||
"Close": "Închide",
|
|
||||||
"Command": "Comandă",
|
|
||||||
"Comment, when used at the start of a line": "Comentariu, când este folosit la începutul unei linii",
|
|
||||||
"Compression": "Compresie",
|
|
||||||
"Connection Error": "Eroare de conexiune",
|
|
||||||
"Copied from elsewhere": "Copiat din altă parte",
|
|
||||||
"Copied from original": "Copiat din original",
|
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright ©2015 Următorii Contribuitori:",
|
|
||||||
"Danger!": "Danger!",
|
|
||||||
"Delete": "Şterge",
|
|
||||||
"Deleted": "Șters",
|
|
||||||
"Device ID": "ID Dispozitiv",
|
|
||||||
"Device Identification": "Identificare Dispozitiv",
|
|
||||||
"Device Name": "Nume Dispozitiv",
|
|
||||||
"Device {%device%} ({%address%}) wants to connect. Add new device?": "Dispozitivul{{dispoztiv}}({{adresă}})vrea sa se conecteze.Adaug un dispozitiv nou?",
|
|
||||||
"Devices": "Dispozitiv",
|
|
||||||
"Disconnected": "Deconectat",
|
|
||||||
"Discovery": "Discovery",
|
|
||||||
"Documentation": "Documentaţie",
|
|
||||||
"Download Rate": "Viteză de Descărcare",
|
|
||||||
"Downloaded": "Descărcat",
|
|
||||||
"Downloading": "Se descarcă",
|
|
||||||
"Edit": "Modifică",
|
|
||||||
"Edit Device": "Modifică Dispozitiv",
|
|
||||||
"Edit Folder": "Modifică Mapa",
|
|
||||||
"Editing": "Modificare",
|
|
||||||
"Enable Relaying": "Enable Relaying",
|
|
||||||
"Enable UPnP": "Activează UPnP",
|
|
||||||
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.",
|
|
||||||
"Enter ignore patterns, one per line.": "Adaugă șabloanele de ignorare, câte una pe linie.",
|
|
||||||
"Error": "Eroare",
|
|
||||||
"External File Versioning": "Administrare externă a versiunilor documentului",
|
|
||||||
"Failed Items": "Failed Items",
|
|
||||||
"File Pull Order": "File Pull Order",
|
|
||||||
"File Versioning": "Versiune Fișier",
|
|
||||||
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Biții de autorizare sînt excluși cînd se analizează modificările. A se utiliza pe sisteme FAT. ",
|
|
||||||
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Files are moved to .stversions folder when replaced or deleted by Syncthing.",
|
|
||||||
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Documentele sînt mutate într-un fișier .stversions conținînd versiuni datate atunci cînd sînt șterse sau înlocuite de Syncthing. ",
|
|
||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Fișierele sunt protejate de schimbările făcute pe alte dispozitive dar schimbările efectuate pe acest dispozitiv vor fi trimise catre restul grupului.",
|
|
||||||
"Folder": "Mapă",
|
|
||||||
"Folder ID": "ID Mapă",
|
|
||||||
"Folder Master": "Master Măpi",
|
|
||||||
"Folder Path": "Locaţie Mapei",
|
|
||||||
"Folders": "Mapă",
|
|
||||||
"GUI": "GUI",
|
|
||||||
"GUI Authentication Password": "Parolă Interfaţă",
|
|
||||||
"GUI Authentication User": "User Interfaţă",
|
|
||||||
"GUI Listen Addresses": "Adresă Interfaţă",
|
|
||||||
"Generate": "Generează",
|
|
||||||
"Global Discovery": "Găsire Globală",
|
|
||||||
"Global Discovery Server": "Server pentru Găsirea Globală",
|
|
||||||
"Global Discovery Servers": "Global Discovery Servers",
|
|
||||||
"Global State": "Status Global",
|
|
||||||
"Help": "Help",
|
|
||||||
"Home page": "Home page",
|
|
||||||
"Ignore": "Ignoră",
|
|
||||||
"Ignore Patterns": "Reguli de excludere",
|
|
||||||
"Ignore Permissions": "Ignoră Permisiuni",
|
|
||||||
"Incoming Rate Limit (KiB/s)": "Limită Viteză de Download (KB/s)",
|
|
||||||
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Incorrect configuration may damage your folder contents and render Syncthing inoperable.",
|
|
||||||
"Introducer": "Dispozitiv Inițiator",
|
|
||||||
"Inversion of the given condition (i.e. do not exclude)": "Inversarea condiției (de ex., nu exclude)",
|
|
||||||
"Keep Versions": "Păstrează Versiuni",
|
|
||||||
"Largest First": "Largest First",
|
|
||||||
"Last File Received": "Ultimul Fișier Primit",
|
|
||||||
"Last seen": "Ultima vizionare",
|
|
||||||
"Later": "Mai tîrziu",
|
|
||||||
"Local Discovery": "Găsire Locală",
|
|
||||||
"Local State": "Status Local",
|
|
||||||
"Local State (Total)": "Local State (Total)",
|
|
||||||
"Major Upgrade": "Major Upgrade",
|
|
||||||
"Maximum Age": "Vârsta Maximă",
|
|
||||||
"Metadata Only": "Doar Metadate",
|
|
||||||
"Minimum Free Disk Space": "Minimum Free Disk Space",
|
|
||||||
"Move to top of queue": "Mută la începutul listei",
|
|
||||||
"Multi level wildcard (matches multiple directory levels)": "Asterisc de nivel multiplu (corespunde fișierelor și sub-fișierelor)",
|
|
||||||
"Never": "Niciodată",
|
|
||||||
"New Device": "Dispozitiv Nou",
|
|
||||||
"New Folder": "Mapă Nouă",
|
|
||||||
"Newest First": "Newest First",
|
|
||||||
"No": "Nu",
|
|
||||||
"No File Versioning": "Fără versiuni ale documentelor",
|
|
||||||
"Notice": "Mențiuni",
|
|
||||||
"OK": "OK",
|
|
||||||
"Off": "Închis",
|
|
||||||
"Oldest First": "Oldest First",
|
|
||||||
"Options": "Opțiuni",
|
|
||||||
"Out of Sync": "Out of Sync",
|
|
||||||
"Out of Sync Items": "Elemente Nesincronizate",
|
|
||||||
"Outgoing Rate Limit (KiB/s)": "Limită Viteză de Upload (KB/s)",
|
|
||||||
"Override Changes": "Suprascrie Schimbări",
|
|
||||||
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Localizarea fișierului în acest computer. Dacă nu există, va fi creat. Tilda (~) înlocuiește ",
|
|
||||||
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Locul unde vor fi stocate versiunile (a se lăsa neschimbat pentru fișierul .stversions din fișier). ",
|
|
||||||
"Pause": "Pauză",
|
|
||||||
"Paused": "Paused",
|
|
||||||
"Please consult the release notes before performing a major upgrade.": "Please consult the release notes before performing a major upgrade.",
|
|
||||||
"Please set a GUI Authentication User and Password in the Settings dialog.": "Please set a GUI Authentication User and Password in the Settings dialog.",
|
|
||||||
"Please wait": "Aşteaptă",
|
|
||||||
"Preview": "Previzualizează",
|
|
||||||
"Preview Usage Report": "Vezi raportul de utilizare",
|
|
||||||
"Quick guide to supported patterns": "Ghid rapid pentru regulile suportate",
|
|
||||||
"RAM Utilization": "RAM",
|
|
||||||
"Random": "Random",
|
|
||||||
"Relay Servers": "Relay Servers",
|
|
||||||
"Relayed via": "Relayed via",
|
|
||||||
"Relays": "Relays",
|
|
||||||
"Release Notes": "Release Notes",
|
|
||||||
"Remove": "Remove",
|
|
||||||
"Rescan": "Rescanează",
|
|
||||||
"Rescan All": "Rescaneaza Tot",
|
|
||||||
"Rescan Interval": "Interval Scanare",
|
|
||||||
"Restart": "Restart",
|
|
||||||
"Restart Needed": "Restart Necesar",
|
|
||||||
"Restarting": "Se restartează",
|
|
||||||
"Resume": "Resume",
|
|
||||||
"Reused": "Refolosit",
|
|
||||||
"Save": "Salvează",
|
|
||||||
"Scan Time Remaining": "Scan Time Remaining",
|
|
||||||
"Scanning": "Scanează",
|
|
||||||
"Select the devices to share this folder with.": "Selectează dispozitivele pentru care să fie disponibil această mapă.",
|
|
||||||
"Select the folders to share with this device.": "Alege mapele pe care vrei sa le imparți cu acest dispozitiv.",
|
|
||||||
"Settings": "Setări",
|
|
||||||
"Share": "Împarte",
|
|
||||||
"Share Folder": "Împarte Mapa",
|
|
||||||
"Share Folders With Device": "Împarte Mapa Cu Dispozitivul",
|
|
||||||
"Share With Devices": "Împarte Cu Dispozitivul",
|
|
||||||
"Share this folder?": "Împarte această mapă?",
|
|
||||||
"Shared With": "Împarte Cu",
|
|
||||||
"Short identifier for the folder. Must be the same on all cluster devices.": "Identificator scurt al fișierului. Trebuie să fie același pe toate mașinile. ",
|
|
||||||
"Show ID": "Arată ID",
|
|
||||||
"Show QR": "Show QR",
|
|
||||||
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Vizibil în locul ID-ului dispozitivului într-un grup. Va fi sugerat celorlalte dispozitive ca nume opţional. ",
|
|
||||||
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Vizibil în locul ID-ului dispozitivului într-un grup. Va fi înlocuit de numele sugerat de dispozitiv daca nu este completat. ",
|
|
||||||
"Shutdown": "Opreşte",
|
|
||||||
"Shutdown Complete": "Oprește Complet",
|
|
||||||
"Simple File Versioning": "Versiuni simple ale documentelor",
|
|
||||||
"Single level wildcard (matches within a directory only)": "Asterisc de nivel simplu (corespunde doar unui fişier)",
|
|
||||||
"Smallest First": "Smallest First",
|
|
||||||
"Source Code": "Cod Sursă",
|
|
||||||
"Staggered File Versioning": "Versiuni eşalonate ale documentelor",
|
|
||||||
"Start Browser": "Lansează Browser",
|
|
||||||
"Statistics": "Statistici",
|
|
||||||
"Stopped": "Oprit",
|
|
||||||
"Support": "Suport Tehnic",
|
|
||||||
"Sync Protocol Listen Addresses": "Adresa protocolului de sincronizare",
|
|
||||||
"Syncing": "Se sincronizează",
|
|
||||||
"Syncthing has been shut down.": "Sincronizarea a fost oprită.",
|
|
||||||
"Syncthing includes the following software or portions thereof:": "Syncthing include următoarele soft-uri sau părţi din ele:",
|
|
||||||
"Syncthing is restarting.": "Syncthing se restartează.",
|
|
||||||
"Syncthing is upgrading.": "Syncthing se actualizează.",
|
|
||||||
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing pare a fi oprit sau aveţi probleme cu conexiunea la internet. Reluare... ",
|
|
||||||
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing pare a avea probleme prelucrînd solicitarea dumneavoastră. Reîncărcaţi pagina sau porniţi Syncthing din nou dacă problema continuă. ",
|
|
||||||
"The Syncthing admin interface is configured to allow remote access without a password.": "The Syncthing admin interface is configured to allow remote access without a password.",
|
|
||||||
"The aggregated statistics are publicly available at {%url%}.": "Statisticile în ansamblu sînt accesibile public la {{url}}.",
|
|
||||||
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Configuraţia a fost salvată dar nu şi activată. Syncthing trebuie să repornească pentru a activa noua configuraţie.",
|
|
||||||
"The device ID cannot be blank.": "ID-ul dispozitivului nu poate fi gol.",
|
|
||||||
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).",
|
|
||||||
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "ID-ul dispozitivului ce trebuie introdus aici poate fi aflat la \"Editează > Arată ID-ul\" pe celălalt dispozitiv. Spaţiile şi liniile oblice sînt opţionale (vor fi ignorate). ",
|
|
||||||
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "Raportul codat de utilizare este trimit zilnic. Este folosit pentru studierea platformelor comune, dimensiunilor fişierelor şi versiunea aplicaţiilor. În cazul în care setul de date trimis este modificat, acest dialog va aparea din nou. ",
|
|
||||||
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "ID-ul dispozitivului nu pare a fi valid.El trebuie sa fie format dintrun șir din 52 ori 56 de caractere formate din litere și cifre, cu spatii și linii opțional.",
|
|
||||||
"The first command line parameter is the folder path and the second parameter is the relative path in the folder.": "The first command line parameter is the folder path and the second parameter is the relative path in the folder.",
|
|
||||||
"The folder ID cannot be blank.": "ID-ul mapei nu poate fi gol.",
|
|
||||||
"The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "The folder ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.",
|
|
||||||
"The folder ID must be unique.": "ID-ul mapei trebuie să fie unic.",
|
|
||||||
"The folder path cannot be blank.": "Locaţia mapei nu poate fi goală.",
|
|
||||||
"The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.": "The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.",
|
|
||||||
"The following items could not be synchronized.": "The following items could not be synchronized.",
|
|
||||||
"The maximum age must be a number and cannot be blank.": "Vârsta maximă trebuie să fie un număr şi nu poate fi goală.",
|
|
||||||
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Câte zile să se păstreze o versiune (setează 0 pentru nelimitat)",
|
|
||||||
"The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).": "The minimum free disk space percentage must be a non-negative number between 0 and 100 (inclusive).",
|
|
||||||
"The number of days must be a number and cannot be blank.": "The number of days must be a number and cannot be blank.",
|
|
||||||
"The number of days to keep files in the trash can. Zero means forever.": "Numărul de zile pentru a păstra fișierele in urnă.Zero înseamnă permanent.",
|
|
||||||
"The number of old versions to keep, per file.": "Numărul de versiuni vechi de salvat per fişier.",
|
|
||||||
"The number of versions must be a number and cannot be blank.": "Numărul de versiuni trebuie să fie un număr şi nu poate fi gol.",
|
|
||||||
"The path cannot be blank.": "Locația nu poate fi goală.",
|
|
||||||
"The rate limit must be a non-negative number (0: no limit)": "The rate limit must be a non-negative number (0: no limit)",
|
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Intervalul de rescanare trebuie să nu fie un număr negativ de secunde. ",
|
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "They are retried automatically and will be synced when the error is resolved.",
|
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
|
||||||
"This is a major version upgrade.": "This is a major version upgrade.",
|
|
||||||
"Trash Can File Versioning": "Trash Can File Versioning",
|
|
||||||
"Unknown": "Necunoscut",
|
|
||||||
"Unshared": "Neîmpărțit",
|
|
||||||
"Unused": "Nefolosit",
|
|
||||||
"Up to Date": "La Zi",
|
|
||||||
"Updated": "Updated",
|
|
||||||
"Upgrade": "Upgrade",
|
|
||||||
"Upgrade To {%version%}": "Actualizează La Versiunea {{version}}",
|
|
||||||
"Upgrading": "Se Actualizează",
|
|
||||||
"Upload Rate": "Viteză Upload",
|
|
||||||
"Uptime": "Uptime",
|
|
||||||
"Use HTTPS for GUI": "Foloseşte HTTPS pentru interfaţă",
|
|
||||||
"Version": "Versiune",
|
|
||||||
"Versions Path": "Locaţie Versiuni",
|
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versiunile sînt şterse în mod automat dacă sînt mai vechi decît vîrsta maximă sau depăşesc numărul de documente permise într-un anume interval. ",
|
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Când adaugi un dispozitiv nou, trebuie să adaugi şi dispozitivul curent în dispozitivul nou.",
|
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Cînd adăugaţi un fişier nou, nu uitaţi că ID-ul fişierului va rămîne acelaşi pe toate dispozitivele. Iar literele mari sînt diferite de literele mici. ",
|
|
||||||
"Yes": "Da",
|
|
||||||
"You must keep at least one version.": "Trebuie să păstrezi cel puţin o versiune.",
|
|
||||||
"days": "Zile",
|
|
||||||
"full documentation": "toată documentaţia",
|
|
||||||
"items": "obiecte",
|
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{Dispozitivul}} vrea să transmită mapa {{Mapa}}"
|
|
||||||
}
|
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Добавить",
|
"Add": "Добавить",
|
||||||
"Add Device": "Добавить устройство",
|
"Add Device": "Добавить устройство",
|
||||||
"Add Folder": "Добавить папку",
|
"Add Folder": "Добавить папку",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Добавить новую папку?",
|
"Add new folder?": "Добавить новую папку?",
|
||||||
"Address": "Адрес",
|
"Address": "Адрес",
|
||||||
"Addresses": "Адреса",
|
"Addresses": "Адреса",
|
||||||
"Advanced": "Дополнительно",
|
"Advanced": "Дополнительно",
|
||||||
"Advanced Configuration": "Дополнительные настройки",
|
"Advanced Configuration": "Дополнительные настройки",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Все данные",
|
"All Data": "Все данные",
|
||||||
"Allow Anonymous Usage Reporting?": "Разрешить сбор анонимной статистики использования?",
|
"Allow Anonymous Usage Reporting?": "Разрешить сбор анонимной статистики использования?",
|
||||||
"Alphabetic": "По алфавиту",
|
"Alphabetic": "По алфавиту",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Ошибка подключения",
|
"Connection Error": "Ошибка подключения",
|
||||||
"Copied from elsewhere": "Скопировано из другого места",
|
"Copied from elsewhere": "Скопировано из другого места",
|
||||||
"Copied from original": "Скопировано с оригинала",
|
"Copied from original": "Скопировано с оригинала",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Все права защищены ©, 2015 участники:",
|
"Copyright © 2015 the following Contributors:": "Все права защищены ©, 2015 участники:",
|
||||||
"Danger!": "Опасно!",
|
"Danger!": "Опасно!",
|
||||||
"Delete": "Удалить",
|
"Delete": "Удалить",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Файлы защищены от изменений сделанных на других устройствах, но изменения сделанные на этом устройстве будут отправлены всему кластеру.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Файлы защищены от изменений сделанных на других устройствах, но изменения сделанные на этом устройстве будут отправлены всему кластеру.",
|
||||||
"Folder": "Папка",
|
"Folder": "Папка",
|
||||||
"Folder ID": "ID папки",
|
"Folder ID": "ID папки",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Папка-оригинал",
|
"Folder Master": "Папка-оригинал",
|
||||||
"Folder Path": "Путь к папке",
|
"Folder Path": "Путь к папке",
|
||||||
"Folders": "Папки",
|
"Folders": "Папки",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "ОК",
|
"OK": "ОК",
|
||||||
"Off": "Отключить",
|
"Off": "Отключить",
|
||||||
"Oldest First": "Сначала старые",
|
"Oldest First": "Сначала старые",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Настройки",
|
"Options": "Настройки",
|
||||||
"Out of Sync": "Нет синхронизации",
|
"Out of Sync": "Нет синхронизации",
|
||||||
"Out of Sync Items": "Не синхронизированные пункты",
|
"Out of Sync Items": "Не синхронизированные пункты",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Релей через",
|
"Relayed via": "Релей через",
|
||||||
"Relays": "Релеи",
|
"Relays": "Релеи",
|
||||||
"Release Notes": "Замечания к версии",
|
"Release Notes": "Замечания к версии",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Удалить",
|
"Remove": "Удалить",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Пересканирование",
|
"Rescan": "Пересканирование",
|
||||||
"Rescan All": "Пересканировать все",
|
"Rescan All": "Пересканировать все",
|
||||||
"Rescan Interval": "Интервал пересканирования",
|
"Rescan Interval": "Интервал пересканирования",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "Скорость должна быть неотрицательным числом (0: нет ограничения)",
|
"The rate limit must be a non-negative number (0: no limit)": "Скорость должна быть неотрицательным числом (0: нет ограничения)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Интервал пересканирования должен быть неотрицательным количеством секунд.",
|
"The rescan interval must be a non-negative number of seconds.": "Интервал пересканирования должен быть неотрицательным количеством секунд.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Будут синхронизированы автоматически когда ошибка будет исправлена.",
|
"They are retried automatically and will be synced when the error is resolved.": "Будут синхронизированы автоматически когда ошибка будет исправлена.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Это может дать доступ хакерам для чтения и изменения любых файлов на вашем компьютере.",
|
"This can easily give hackers access to read and change any files on your computer.": "Это может дать доступ хакерам для чтения и изменения любых файлов на вашем компьютере.",
|
||||||
"This is a major version upgrade.": "Это обновление основной версии продукта.",
|
"This is a major version upgrade.": "Это обновление основной версии продукта.",
|
||||||
"Trash Can File Versioning": "Использовать версионность для файлов в Корзине",
|
"Trash Can File Versioning": "Использовать версионность для файлов в Корзине",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Версия",
|
"Version": "Версия",
|
||||||
"Versions Path": "Путь к версиям",
|
"Versions Path": "Путь к версиям",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Версии удаляются автоматически, если они существуют дольше максимального срока или превышают разрешённое количество файлов за интервал.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Версии удаляются автоматически, если они существуют дольше максимального срока или превышают разрешённое количество файлов за интервал.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Когда добавляете устройство, помните о том, что это же устройство должно быть добавлено и другой стороной.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Когда добавляете устройство, помните о том, что это же устройство должно быть добавлено и другой стороной.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Когда добавляете новую папку, помните, что ID папок используются для того, чтобы связывать папки между всеми устройствами. Они чувствительны к регистру и должны совпадать на всех используемых устройствах.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Когда добавляете новую папку, помните, что ID папок используются для того, чтобы связывать папки между всеми устройствами. Они чувствительны к регистру и должны совпадать на всех используемых устройствах.",
|
||||||
"Yes": "Да",
|
"Yes": "Да",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "Дней",
|
"days": "Дней",
|
||||||
"full documentation": "полная документация",
|
"full documentation": "полная документация",
|
||||||
"items": "элементы",
|
"items": "элементы",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} хочет поделиться папкой \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} хочет поделиться папкой \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"A device with that ID is already added.": "A device with that ID is already added.",
|
"A device with that ID is already added.": "En enhet med det ID är redan tillagt.",
|
||||||
"A negative number of days doesn't make sense.": "Negativt antal dagar är inte troligt.",
|
"A negative number of days doesn't make sense.": "Negativt antal dagar är inte troligt.",
|
||||||
"A new major version may not be compatible with previous versions.": "En ny huvudversion kan eventuellt vara inkompatibel med tidigare versioner.",
|
"A new major version may not be compatible with previous versions.": "En ny huvudversion kan eventuellt vara inkompatibel med tidigare versioner.",
|
||||||
"API Key": "API-nyckel",
|
"API Key": "API-nyckel",
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Lägg till",
|
"Add": "Lägg till",
|
||||||
"Add Device": "Lägg till enhet",
|
"Add Device": "Lägg till enhet",
|
||||||
"Add Folder": "Lägg till katalog",
|
"Add Folder": "Lägg till katalog",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Lägg till katalog?",
|
"Add new folder?": "Lägg till katalog?",
|
||||||
"Address": "Adress",
|
"Address": "Adress",
|
||||||
"Addresses": "Adresser",
|
"Addresses": "Adresser",
|
||||||
"Advanced": "Avancerat",
|
"Advanced": "Avancerat",
|
||||||
"Advanced Configuration": "Avancerad konfiguration",
|
"Advanced Configuration": "Avancerad konfiguration",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "All data",
|
"All Data": "All data",
|
||||||
"Allow Anonymous Usage Reporting?": "Tillåt anonym användarstatistik?",
|
"Allow Anonymous Usage Reporting?": "Tillåt anonym användarstatistik?",
|
||||||
"Alphabetic": "Alfabetisk",
|
"Alphabetic": "Alfabetisk",
|
||||||
@@ -32,8 +34,9 @@
|
|||||||
"Connection Error": "Anslutningsproblem",
|
"Connection Error": "Anslutningsproblem",
|
||||||
"Copied from elsewhere": "Kopierat utifrån",
|
"Copied from elsewhere": "Kopierat utifrån",
|
||||||
"Copied from original": "Oförändrat",
|
"Copied from original": "Oförändrat",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 följande medverkande:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 följande medverkande:",
|
||||||
"Danger!": "Danger!",
|
"Danger!": "Fara!",
|
||||||
"Delete": "Radera",
|
"Delete": "Radera",
|
||||||
"Deleted": "Borttaget",
|
"Deleted": "Borttaget",
|
||||||
"Device ID": "Enhets-ID",
|
"Device ID": "Enhets-ID",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Filer skyddas från ändringar gjorda på andra enheter, men ändringar som görs på den här noden skickas till de andra klustermedlemmarna.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Filer skyddas från ändringar gjorda på andra enheter, men ändringar som görs på den här noden skickas till de andra klustermedlemmarna.",
|
||||||
"Folder": "Katalog",
|
"Folder": "Katalog",
|
||||||
"Folder ID": "Katalog-ID",
|
"Folder ID": "Katalog-ID",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Huvudlagring",
|
"Folder Master": "Huvudlagring",
|
||||||
"Folder Path": "Sökväg",
|
"Folder Path": "Sökväg",
|
||||||
"Folders": "Kataloger",
|
"Folders": "Kataloger",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Av",
|
"Off": "Av",
|
||||||
"Oldest First": "Äldst först",
|
"Oldest First": "Äldst först",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Alternativ",
|
"Options": "Alternativ",
|
||||||
"Out of Sync": "Osynkad",
|
"Out of Sync": "Osynkad",
|
||||||
"Out of Sync Items": "Osynkade poster",
|
"Out of Sync Items": "Osynkade poster",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Vidarbefordras via",
|
"Relayed via": "Vidarbefordras via",
|
||||||
"Relays": "Vidarbefordringar",
|
"Relays": "Vidarbefordringar",
|
||||||
"Release Notes": "versionsnyheter",
|
"Release Notes": "versionsnyheter",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Ta bort",
|
"Remove": "Ta bort",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Uppdatera",
|
"Rescan": "Uppdatera",
|
||||||
"Rescan All": "Uppdatera alla",
|
"Rescan All": "Uppdatera alla",
|
||||||
"Rescan Interval": "Uppdateringsintervall",
|
"Rescan Interval": "Uppdateringsintervall",
|
||||||
@@ -142,7 +149,7 @@
|
|||||||
"Resume": "Återuppta",
|
"Resume": "Återuppta",
|
||||||
"Reused": "Återanvänt",
|
"Reused": "Återanvänt",
|
||||||
"Save": "Spara",
|
"Save": "Spara",
|
||||||
"Scan Time Remaining": "Scan Time Remaining",
|
"Scan Time Remaining": "Skanna Återstående Tid",
|
||||||
"Scanning": "Uppdaterar",
|
"Scanning": "Uppdaterar",
|
||||||
"Select the devices to share this folder with.": "Ange enheterna att dela den här katalogen med.",
|
"Select the devices to share this folder with.": "Ange enheterna att dela den här katalogen med.",
|
||||||
"Select the folders to share with this device.": "Välj kataloger att dela med den här enheten.",
|
"Select the folders to share with this device.": "Välj kataloger att dela med den här enheten.",
|
||||||
@@ -155,7 +162,7 @@
|
|||||||
"Shared With": "Delad med",
|
"Shared With": "Delad med",
|
||||||
"Short identifier for the folder. Must be the same on all cluster devices.": "Kort identifieringssträng för katalogen. Måste vara samma på alla enheter i klustret.",
|
"Short identifier for the folder. Must be the same on all cluster devices.": "Kort identifieringssträng för katalogen. Måste vara samma på alla enheter i klustret.",
|
||||||
"Show ID": "Visa ID",
|
"Show ID": "Visa ID",
|
||||||
"Show QR": "Show QR",
|
"Show QR": "Visa QR",
|
||||||
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Visas i stället för enhets-ID. Skickas till andra enheter som namn på denna enhet.",
|
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Visas i stället för enhets-ID. Skickas till andra enheter som namn på denna enhet.",
|
||||||
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Visas i stället för enhets-ID. Sätts till namnet på den andra enheten vid första anslutning om det lämnas tomt.",
|
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Visas i stället för enhets-ID. Sätts till namnet på den andra enheten vid första anslutning om det lämnas tomt.",
|
||||||
"Shutdown": "Stäng av",
|
"Shutdown": "Stäng av",
|
||||||
@@ -177,11 +184,11 @@
|
|||||||
"Syncthing is upgrading.": "Syncthing uppgraderas.",
|
"Syncthing is upgrading.": "Syncthing uppgraderas.",
|
||||||
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing verkar avstängd, eller finns det problem med din Internetanslutning. Försöker igen...",
|
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing verkar avstängd, eller finns det problem med din Internetanslutning. Försöker igen...",
|
||||||
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing verkar ha drabbats av ett problem. Uppdatera sidan eller starta om Syncthing om problemet kvarstår.",
|
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing verkar ha drabbats av ett problem. Uppdatera sidan eller starta om Syncthing om problemet kvarstår.",
|
||||||
"The Syncthing admin interface is configured to allow remote access without a password.": "The Syncthing admin interface is configured to allow remote access without a password.",
|
"The Syncthing admin interface is configured to allow remote access without a password.": "Syncthing administratör gränssnittet är konfigurerat för att tillåta fjärrtillträde utan ett lösenord.",
|
||||||
"The aggregated statistics are publicly available at {%url%}.": "Sammanställd statistik finns publikt tillgänglig på {{url}}.",
|
"The aggregated statistics are publicly available at {%url%}.": "Sammanställd statistik finns publikt tillgänglig på {{url}}.",
|
||||||
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Konfigurationen har sparats men inte aktiverats. Syncthing måste startas om för att aktivera den nya konfigurationen.",
|
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Konfigurationen har sparats men inte aktiverats. Syncthing måste startas om för att aktivera den nya konfigurationen.",
|
||||||
"The device ID cannot be blank.": "Enhets-ID kan inte vara tomt.",
|
"The device ID cannot be blank.": "Enhets-ID kan inte vara tomt.",
|
||||||
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).",
|
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Enhets-ID som behövs här kan du hitta i \"Redigera > Visa ID\"-dialogen på den andra enheten. Mellanrum och bindestreck är valfria (ignoreras).",
|
||||||
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Enhets-ID som behövs här kan du hitta i \"Redigera > Visa ID\"-dialogen på den andra enheten. Mellanrum och bindestreck är valfria (ignoreras).",
|
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Enhets-ID som behövs här kan du hitta i \"Redigera > Visa ID\"-dialogen på den andra enheten. Mellanrum och bindestreck är valfria (ignoreras).",
|
||||||
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "Den krypterade användarstatistiken skickas dagligen. Den används för att spåra vanliga plattformar, katalogstorlekar och versioner. Om datan som rapporteras ändras så kommer du att bli tillfrågad igen.",
|
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "Den krypterade användarstatistiken skickas dagligen. Den används för att spåra vanliga plattformar, katalogstorlekar och versioner. Om datan som rapporteras ändras så kommer du att bli tillfrågad igen.",
|
||||||
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "Det inmatade enhets-ID:t verkar inte korrekt. Det ska vara en 52 eller 56 teckens sträng bestående av siffror och bokstäver, eventuellt med mellanrum och bindestreck.",
|
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "Det inmatade enhets-ID:t verkar inte korrekt. Det ska vara en 52 eller 56 teckens sträng bestående av siffror och bokstäver, eventuellt med mellanrum och bindestreck.",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "Frekvensgränsen måste vara ett icke-negativt tal (0: ingen gräns)",
|
"The rate limit must be a non-negative number (0: no limit)": "Frekvensgränsen måste vara ett icke-negativt tal (0: ingen gräns)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Förnyelseintervallet måste vara ett positivt antal sekunder",
|
"The rescan interval must be a non-negative number of seconds.": "Förnyelseintervallet måste vara ett positivt antal sekunder",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "De omprövas automatiskt och kommer att synkroniseras när felet är löst.",
|
"They are retried automatically and will be synced when the error is resolved.": "De omprövas automatiskt och kommer att synkroniseras när felet är löst.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
||||||
"This is a major version upgrade.": "Det här är en stor uppgradering.",
|
"This is a major version upgrade.": "Det här är en stor uppgradering.",
|
||||||
"Trash Can File Versioning": "Versionshantering på filer i papperskorgen",
|
"Trash Can File Versioning": "Versionshantering på filer i papperskorgen",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Version",
|
"Version": "Version",
|
||||||
"Versions Path": "Katalog för versioner",
|
"Versions Path": "Katalog för versioner",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versioner tas bort automatiskt när de är äldre än den maximala åldersgränsen eller överstiger frekvensen i sitt interval.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versioner tas bort automatiskt när de är äldre än den maximala åldersgränsen eller överstiger frekvensen i sitt interval.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "När du lägger till en ny enhet, kom ihåg att den här enheten måste läggas till på den andra enheten också.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "När du lägger till en ny enhet, kom ihåg att den här enheten måste läggas till på den andra enheten också.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "När du lägger till ny katalog, tänk på att katalog-ID:t knyter ihop katalogen mellan olika noder. De måste vara exakt desamma mellan noder och stora eller små bokstäver har betydelse.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "När du lägger till ny katalog, tänk på att katalog-ID:t knyter ihop katalogen mellan olika noder. De måste vara exakt desamma mellan noder och stora eller små bokstäver har betydelse.",
|
||||||
"Yes": "Ja",
|
"Yes": "Ja",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "dagar",
|
"days": "dagar",
|
||||||
"full documentation": "fullständig dokumentation",
|
"full documentation": "fullständig dokumentation",
|
||||||
"items": "poster",
|
"items": "poster",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} vill dela katalogen \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} vill dela katalogen \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Ekle",
|
"Add": "Ekle",
|
||||||
"Add Device": "Cihaz Ekle",
|
"Add Device": "Cihaz Ekle",
|
||||||
"Add Folder": "Klasör Ekle",
|
"Add Folder": "Klasör Ekle",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Yeni klasör ekle?",
|
"Add new folder?": "Yeni klasör ekle?",
|
||||||
"Address": "Adres",
|
"Address": "Adres",
|
||||||
"Addresses": "Adresler",
|
"Addresses": "Adresler",
|
||||||
"Advanced": "Gelişmiş Düzey",
|
"Advanced": "Gelişmiş Düzey",
|
||||||
"Advanced Configuration": "Gelişmiş Yapılandırma",
|
"Advanced Configuration": "Gelişmiş Yapılandırma",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Bütün Veriler",
|
"All Data": "Bütün Veriler",
|
||||||
"Allow Anonymous Usage Reporting?": "Anonim kullanımın raporlanmasına izin veriyor musun ?",
|
"Allow Anonymous Usage Reporting?": "Anonim kullanımın raporlanmasına izin veriyor musun ?",
|
||||||
"Alphabetic": "Alfabetik",
|
"Alphabetic": "Alfabetik",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Bağlantı hatası",
|
"Connection Error": "Bağlantı hatası",
|
||||||
"Copied from elsewhere": "Başka bir yerden kopyalanmış",
|
"Copied from elsewhere": "Başka bir yerden kopyalanmış",
|
||||||
"Copied from original": "Aslından kopyalanmış",
|
"Copied from original": "Aslından kopyalanmış",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Telif Hakkı © 2015 katkıda bulunanlar:",
|
"Copyright © 2015 the following Contributors:": "Telif Hakkı © 2015 katkıda bulunanlar:",
|
||||||
"Danger!": "Tehlike!",
|
"Danger!": "Tehlike!",
|
||||||
"Delete": "Sil",
|
"Delete": "Sil",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Dosyalar diğer cihazlarda yapılan değişikliklerden korunur, ancak bu cihazdaki değişiklikler kümedeki diğer cihazlara gönderilir.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Dosyalar diğer cihazlarda yapılan değişikliklerden korunur, ancak bu cihazdaki değişiklikler kümedeki diğer cihazlara gönderilir.",
|
||||||
"Folder": "Klasör",
|
"Folder": "Klasör",
|
||||||
"Folder ID": "Klasör ID",
|
"Folder ID": "Klasör ID",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Ana Klasör",
|
"Folder Master": "Ana Klasör",
|
||||||
"Folder Path": "Klasör Yolu",
|
"Folder Path": "Klasör Yolu",
|
||||||
"Folders": "Klasörler",
|
"Folders": "Klasörler",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "Tamam",
|
"OK": "Tamam",
|
||||||
"Off": "Kapalı",
|
"Off": "Kapalı",
|
||||||
"Oldest First": "En eski olan önce",
|
"Oldest First": "En eski olan önce",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Seçenekler",
|
"Options": "Seçenekler",
|
||||||
"Out of Sync": "Eşzamanlama Dışı",
|
"Out of Sync": "Eşzamanlama Dışı",
|
||||||
"Out of Sync Items": "Eşzamanlama dışında kalan Öğeler",
|
"Out of Sync Items": "Eşzamanlama dışında kalan Öğeler",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Relayed via",
|
"Relayed via": "Relayed via",
|
||||||
"Relays": "Röleler",
|
"Relays": "Röleler",
|
||||||
"Release Notes": "Sürüm Notları",
|
"Release Notes": "Sürüm Notları",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Kaldır",
|
"Remove": "Kaldır",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Tekrar Tara",
|
"Rescan": "Tekrar Tara",
|
||||||
"Rescan All": "Tümünü Tekrar Tara",
|
"Rescan All": "Tümünü Tekrar Tara",
|
||||||
"Rescan Interval": "Tarama Aralığı",
|
"Rescan Interval": "Tarama Aralığı",
|
||||||
@@ -181,7 +188,7 @@
|
|||||||
"The aggregated statistics are publicly available at {%url%}.": "Toplanan halka açık istatistiklere ulaşabileceğiniz adres {{url}}.",
|
"The aggregated statistics are publicly available at {%url%}.": "Toplanan halka açık istatistiklere ulaşabileceğiniz adres {{url}}.",
|
||||||
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Yapılandırma kaydedildi ancak etkinleştirilmedi. Etkinleştirmek için Syncthing yeniden başlatılmalı.",
|
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Yapılandırma kaydedildi ancak etkinleştirilmedi. Etkinleştirmek için Syncthing yeniden başlatılmalı.",
|
||||||
"The device ID cannot be blank.": "Cihaz ID boş olamaz.",
|
"The device ID cannot be blank.": "Cihaz ID boş olamaz.",
|
||||||
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).",
|
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Buraya girilecek olan aygıt ID'si diğer cihazlarda, \"Eylemler > ID Göster\" penceresinde bulunabilir. Boşluklar ve çizgiler isteğe bağlıdır (yoksayılmış).",
|
||||||
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Buraya girilecek cihaz ID'si diğer düğümde \"Düzenle > ID Göster\" menüsünden bulunabilir. Boşluk ve kısa çizginin olup olmaması önemli değildir. (İhmal edilir)",
|
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "Buraya girilecek cihaz ID'si diğer düğümde \"Düzenle > ID Göster\" menüsünden bulunabilir. Boşluk ve kısa çizginin olup olmaması önemli değildir. (İhmal edilir)",
|
||||||
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "Şifrelenmiş kullanım bilgisi günlük olarak gönderilir. Platform, klasör büyüklüğü ve uygulama sürümü hakkında bilgi toplanır. Toplanan bilgi çeşidi değişecek olursa, sizden tekrar onay istenecek.",
|
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "Şifrelenmiş kullanım bilgisi günlük olarak gönderilir. Platform, klasör büyüklüğü ve uygulama sürümü hakkında bilgi toplanır. Toplanan bilgi çeşidi değişecek olursa, sizden tekrar onay istenecek.",
|
||||||
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "Girilen cihaz ID'si geçerli gibi gözükmüyor. 52 ya da 56 karakter uzunluğunda, harf ve rakamlardan oluşmalı. Boşlukların ve kısa çizgilerin olup olmaması önemli değildir.",
|
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "Girilen cihaz ID'si geçerli gibi gözükmüyor. 52 ya da 56 karakter uzunluğunda, harf ve rakamlardan oluşmalı. Boşlukların ve kısa çizgilerin olup olmaması önemli değildir.",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "Hız sınırı pozitif bir sayı olmalıdır. (0: sınırsız)",
|
"The rate limit must be a non-negative number (0: no limit)": "Hız sınırı pozitif bir sayı olmalıdır. (0: sınırsız)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Tarama zaman aralığı, saniye cinsinden negatif olmayan bir sayı olmalıdır.",
|
"The rescan interval must be a non-negative number of seconds.": "Tarama zaman aralığı, saniye cinsinden negatif olmayan bir sayı olmalıdır.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Otomatik olarak yeniden deneniyor; hata giderildiğinde eşzamanlama gerçekleştirilecek.",
|
"They are retried automatically and will be synced when the error is resolved.": "Otomatik olarak yeniden deneniyor; hata giderildiğinde eşzamanlama gerçekleştirilecek.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Hacker'ların bilgisayarındaki dosyaları okuma ve değiştirme yetkisine kolayca erişebilmelerini sağlayabilir.",
|
"This can easily give hackers access to read and change any files on your computer.": "Hacker'ların bilgisayarındaki dosyaları okuma ve değiştirme yetkisine kolayca erişebilmelerini sağlayabilir.",
|
||||||
"This is a major version upgrade.": "Birincil sürüm yükseltmesidir.",
|
"This is a major version upgrade.": "Birincil sürüm yükseltmesidir.",
|
||||||
"Trash Can File Versioning": "Çöp Kutusu Dosya Sürümleme",
|
"Trash Can File Versioning": "Çöp Kutusu Dosya Sürümleme",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Sürüm",
|
"Version": "Sürüm",
|
||||||
"Versions Path": "Sürüm Dizin Yolu",
|
"Versions Path": "Sürüm Dizin Yolu",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Sürümler, tanımlı azami süre veya belirlenen zaman aralığı için izin verilen dosya sayısı aşılmışsa kendiliğinden silinir.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Sürümler, tanımlı azami süre veya belirlenen zaman aralığı için izin verilen dosya sayısı aşılmışsa kendiliğinden silinir.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Yeni bir cihaz eklendiğinde, bu cihazın karşı tarafa da eklenmesi gerektiğini unutmayın.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Yeni bir cihaz eklendiğinde, bu cihazın karşı tarafa da eklenmesi gerektiğini unutmayın.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Yeni bir klasör eklendiğinde, Klasör ID'nin klasörleri cihazlar arasında bağlantılandırmak için kullanıldığını unutmayın. Klasör ID'ler büyük - küçük harf duyarlıdır ve bütün cihazlarda tamı tamına eşleşmelidir.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Yeni bir klasör eklendiğinde, Klasör ID'nin klasörleri cihazlar arasında bağlantılandırmak için kullanıldığını unutmayın. Klasör ID'ler büyük - küçük harf duyarlıdır ve bütün cihazlarda tamı tamına eşleşmelidir.",
|
||||||
"Yes": "Evet",
|
"Yes": "Evet",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "günler",
|
"days": "günler",
|
||||||
"full documentation": "belgelendirme içeriğinin tümü",
|
"full documentation": "belgelendirme içeriğinin tümü",
|
||||||
"items": "öğel",
|
"items": "öğel",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} \"{{folder}}\" klasörünü paylaşmak istiyor."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} \"{{folder}}\" klasörünü paylaşmak istiyor.",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"A device with that ID is already added.": "Пристрій з таким ID вже додано.",
|
"A device with that ID is already added.": "Пристрій з таким ID вже додано раніше.",
|
||||||
"A negative number of days doesn't make sense.": "Від'ємна кількість днів немає сенсу.",
|
"A negative number of days doesn't make sense.": "Від'ємна кількість днів немає сенсу.",
|
||||||
"A new major version may not be compatible with previous versions.": "Нова мажорна версія може бути несумісною із попередніми версіями.",
|
"A new major version may not be compatible with previous versions.": "Нова мажорна версія може бути несумісною із попередніми версіями.",
|
||||||
"API Key": "API ключ",
|
"API Key": "API ключ",
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Додати",
|
"Add": "Додати",
|
||||||
"Add Device": "Додати пристрій",
|
"Add Device": "Додати пристрій",
|
||||||
"Add Folder": "Додати директорію",
|
"Add Folder": "Додати директорію",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Додати нову директорію?",
|
"Add new folder?": "Додати нову директорію?",
|
||||||
"Address": "Адреса",
|
"Address": "Адреса",
|
||||||
"Addresses": "Адреси",
|
"Addresses": "Адреси",
|
||||||
"Advanced": "Розширені",
|
"Advanced": "Розширені",
|
||||||
"Advanced Configuration": "Розширена конфігурація",
|
"Advanced Configuration": "Розширена конфігурація",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Усі дані",
|
"All Data": "Усі дані",
|
||||||
"Allow Anonymous Usage Reporting?": "Дозволити програмі збирати анонімну статистику використання?",
|
"Allow Anonymous Usage Reporting?": "Дозволити програмі збирати анонімну статистику використання?",
|
||||||
"Alphabetic": "За алфавітом",
|
"Alphabetic": "За алфавітом",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Помилка з’єднання",
|
"Connection Error": "Помилка з’єднання",
|
||||||
"Copied from elsewhere": "Скопійовано з іншого місця",
|
"Copied from elsewhere": "Скопійовано з іншого місця",
|
||||||
"Copied from original": "Скопійовано з оригіналу",
|
"Copied from original": "Скопійовано з оригіналу",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 наступних контриб’юторів:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 наступних контриб’юторів:",
|
||||||
"Danger!": "Небезпечно!",
|
"Danger!": "Небезпечно!",
|
||||||
"Delete": "Видалити",
|
"Delete": "Видалити",
|
||||||
@@ -42,7 +45,7 @@
|
|||||||
"Device {%device%} ({%address%}) wants to connect. Add new device?": "Пристрій {{device}} ({{address}}) намагається під’єднатися. Додати новий пристрій?",
|
"Device {%device%} ({%address%}) wants to connect. Add new device?": "Пристрій {{device}} ({{address}}) намагається під’єднатися. Додати новий пристрій?",
|
||||||
"Devices": "Пристрої",
|
"Devices": "Пристрої",
|
||||||
"Disconnected": "З’єднання відсутнє",
|
"Disconnected": "З’єднання відсутнє",
|
||||||
"Discovery": "Виявлення",
|
"Discovery": "Сервери обходу NAT",
|
||||||
"Documentation": "Документація",
|
"Documentation": "Документація",
|
||||||
"Download Rate": "Швидкість завантаження",
|
"Download Rate": "Швидкість завантаження",
|
||||||
"Downloaded": "Завантажено",
|
"Downloaded": "Завантажено",
|
||||||
@@ -51,7 +54,7 @@
|
|||||||
"Edit Device": "Редагувати пристрій",
|
"Edit Device": "Редагувати пристрій",
|
||||||
"Edit Folder": "Редагувати директорію",
|
"Edit Folder": "Редагувати директорію",
|
||||||
"Editing": "Редагування",
|
"Editing": "Редагування",
|
||||||
"Enable Relaying": "Enable Relaying",
|
"Enable Relaying": "Увімкнути ретрансляцію (relaying)",
|
||||||
"Enable UPnP": "Увімкнути UPnP",
|
"Enable UPnP": "Увімкнути UPnP",
|
||||||
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Введіть розділені комою (\"tcp://ip:port\", \"tcp://host:port\") адреси або \"dynamic\" для автоматичного визначення адреси.",
|
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Введіть розділені комою (\"tcp://ip:port\", \"tcp://host:port\") адреси або \"dynamic\" для автоматичного визначення адреси.",
|
||||||
"Enter ignore patterns, one per line.": "Введіть шаблони ігнорування, по одному на рядок.",
|
"Enter ignore patterns, one per line.": "Введіть шаблони ігнорування, по одному на рядок.",
|
||||||
@@ -63,10 +66,11 @@
|
|||||||
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Біти прав доступу до файлів будуть проігноровані під час пошуку змін. Використовуйте на файлових системах FAT.",
|
"File permission bits are ignored when looking for changes. Use on FAT file systems.": "Біти прав доступу до файлів будуть проігноровані під час пошуку змін. Використовуйте на файлових системах FAT.",
|
||||||
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Файли, що замінюються або видаляються Syncthing, переміщуються у директорію .stversions. ",
|
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Файли, що замінюються або видаляються Syncthing, переміщуються у директорію .stversions. ",
|
||||||
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Файли будуть поміщатися у директорію .stversions із відповідною позначкою часу, коли вони будуть замінятися або видалятися програмою.",
|
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Файли будуть поміщатися у директорію .stversions із відповідною позначкою часу, коли вони будуть замінятися або видалятися програмою.",
|
||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Файли захищено від змін зроблених на інших пристроях, але зміни зроблені на цьому пристрої будуть надіслані решті кластеру.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Вміст папки захищено від змін, зроблених на інших пристроях, але зміни зроблені на цьому пристрої можна розіслати решті пристроїв кластеру.",
|
||||||
"Folder": "Директорія",
|
"Folder": "Директорія",
|
||||||
"Folder ID": "ID директорії",
|
"Folder ID": "ID директорії",
|
||||||
"Folder Master": "Центральна директорія",
|
"Folder Label": "Folder Label",
|
||||||
|
"Folder Master": "Вважати за оригінал",
|
||||||
"Folder Path": "Шлях до директорії",
|
"Folder Path": "Шлях до директорії",
|
||||||
"Folders": "Директорії",
|
"Folders": "Директорії",
|
||||||
"GUI": "Графічний інтерфейс",
|
"GUI": "Графічний інтерфейс",
|
||||||
@@ -74,14 +78,14 @@
|
|||||||
"GUI Authentication User": "Логін користувача для доступу до панелі управління",
|
"GUI Authentication User": "Логін користувача для доступу до панелі управління",
|
||||||
"GUI Listen Addresses": "Адреса доступу до панелі управління",
|
"GUI Listen Addresses": "Адреса доступу до панелі управління",
|
||||||
"Generate": "Згенерувати",
|
"Generate": "Згенерувати",
|
||||||
"Global Discovery": "Глобальне виявлення",
|
"Global Discovery": "Глобальне виявлення (internet)",
|
||||||
"Global Discovery Server": "Сервер для глобального виявлення",
|
"Global Discovery Server": "Сервер для глобального виявлення",
|
||||||
"Global Discovery Servers": "Global Discovery Servers",
|
"Global Discovery Servers": "Сервери глобального виявлення \n(координації обходу NAT)",
|
||||||
"Global State": "Глобальний статус",
|
"Global State": "Глобальний статус",
|
||||||
"Help": "Допомога",
|
"Help": "Допомога",
|
||||||
"Home page": "Домашня сторінка",
|
"Home page": "Домашня сторінка",
|
||||||
"Ignore": "Ігнорувати",
|
"Ignore": "Ігнорувати",
|
||||||
"Ignore Patterns": "Ігнорувати шаблони",
|
"Ignore Patterns": "Шаблони винятків",
|
||||||
"Ignore Permissions": "Ігнорувати права доступу до файлів",
|
"Ignore Permissions": "Ігнорувати права доступу до файлів",
|
||||||
"Incoming Rate Limit (KiB/s)": "Ліміт швидкості завантаження (КіБ/с)",
|
"Incoming Rate Limit (KiB/s)": "Ліміт швидкості завантаження (КіБ/с)",
|
||||||
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Невірна конфігурація може пошкодити вміст вашої директорії та зробити Syncthing недієздатним.",
|
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Невірна конфігурація може пошкодити вміст вашої директорії та зробити Syncthing недієздатним.",
|
||||||
@@ -92,7 +96,7 @@
|
|||||||
"Last File Received": "Останній завантажений файл",
|
"Last File Received": "Останній завантажений файл",
|
||||||
"Last seen": "З’являвся останній раз",
|
"Last seen": "З’являвся останній раз",
|
||||||
"Later": "Пізніше",
|
"Later": "Пізніше",
|
||||||
"Local Discovery": "Локальне виявлення",
|
"Local Discovery": "Локальне виявлення (LAN)",
|
||||||
"Local State": "Локальний статус",
|
"Local State": "Локальний статус",
|
||||||
"Local State (Total)": "Локальний статус (загалом)",
|
"Local State (Total)": "Локальний статус (загалом)",
|
||||||
"Major Upgrade": "Мажорне оновлення",
|
"Major Upgrade": "Мажорне оновлення",
|
||||||
@@ -111,11 +115,12 @@
|
|||||||
"OK": "Гаразд",
|
"OK": "Гаразд",
|
||||||
"Off": "Вимкнути",
|
"Off": "Вимкнути",
|
||||||
"Oldest First": "Спершу старіші",
|
"Oldest First": "Спершу старіші",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Опції",
|
"Options": "Опції",
|
||||||
"Out of Sync": "Не синхронізовано",
|
"Out of Sync": "Не синхронізовано",
|
||||||
"Out of Sync Items": "Не синхронізовані елементи",
|
"Out of Sync Items": "Не синхронізовані елементи",
|
||||||
"Outgoing Rate Limit (KiB/s)": "Ліміт швидкості віддачі (КіБ/с)",
|
"Outgoing Rate Limit (KiB/s)": "Ліміт швидкості віддачі (КіБ/с)",
|
||||||
"Override Changes": "Перезаписати зміни",
|
"Override Changes": "Розіслати мою версію",
|
||||||
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Шлях до директорії на локальному комп’ютері. Буде створений, якщо такий не існує. Символ тильди (~) може бути використаний як ярлик для",
|
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "Шлях до директорії на локальному комп’ютері. Буде створений, якщо такий не існує. Символ тильди (~) може бути використаний як ярлик для",
|
||||||
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Шлях, де повинні зберігатися версії (залиште порожнім для зберігання в .stversions в середині директорії)",
|
"Path where versions should be stored (leave empty for the default .stversions folder in the folder).": "Шлях, де повинні зберігатися версії (залиште порожнім для зберігання в .stversions в середині директорії)",
|
||||||
"Pause": "Пауза",
|
"Pause": "Пауза",
|
||||||
@@ -128,11 +133,13 @@
|
|||||||
"Quick guide to supported patterns": "Швидкий посібник по шаблонам, що підтримуються",
|
"Quick guide to supported patterns": "Швидкий посібник по шаблонам, що підтримуються",
|
||||||
"RAM Utilization": "Використання RAM",
|
"RAM Utilization": "Використання RAM",
|
||||||
"Random": "Випадково",
|
"Random": "Випадково",
|
||||||
"Relay Servers": "Relay Servers",
|
"Relay Servers": "Сервери ретрансляції",
|
||||||
"Relayed via": "Ретранслювати через",
|
"Relayed via": "Ретранслювати через",
|
||||||
"Relays": "Ретрансляція",
|
"Relays": "Ретранслятори",
|
||||||
"Release Notes": "Примітки до випуску",
|
"Release Notes": "Примітки до випуску",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Видалити",
|
"Remove": "Видалити",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Пересканувати",
|
"Rescan": "Пересканувати",
|
||||||
"Rescan All": "Пересканувати усе",
|
"Rescan All": "Пересканувати усе",
|
||||||
"Rescan Interval": "Інтервал для повторного сканування",
|
"Rescan Interval": "Інтервал для повторного сканування",
|
||||||
@@ -169,7 +176,7 @@
|
|||||||
"Statistics": "Статистика",
|
"Statistics": "Статистика",
|
||||||
"Stopped": "Зупинено",
|
"Stopped": "Зупинено",
|
||||||
"Support": "Підтримка",
|
"Support": "Підтримка",
|
||||||
"Sync Protocol Listen Addresses": "Адреса панелі управління",
|
"Sync Protocol Listen Addresses": "Адреса і вхідний порт протоколу синхронізації",
|
||||||
"Syncing": "Синхронізація",
|
"Syncing": "Синхронізація",
|
||||||
"Syncthing has been shut down.": "Syncthing вимкнено (закрито).",
|
"Syncthing has been shut down.": "Syncthing вимкнено (закрито).",
|
||||||
"Syncthing includes the following software or portions thereof:": "Syncthing містить наступне програмне забезпечення (або його частини):",
|
"Syncthing includes the following software or portions thereof:": "Syncthing містить наступне програмне забезпечення (або його частини):",
|
||||||
@@ -181,7 +188,7 @@
|
|||||||
"The aggregated statistics are publicly available at {%url%}.": "Зібрана статистика публічно доступна за посиланням {{url}}.",
|
"The aggregated statistics are publicly available at {%url%}.": "Зібрана статистика публічно доступна за посиланням {{url}}.",
|
||||||
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Конфігурацію збережено, але не активовано. Необхідно перезапустити Syncthing для того, щоби активувати нову конфігурацію.",
|
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Конфігурацію збережено, але не активовано. Необхідно перезапустити Syncthing для того, щоби активувати нову конфігурацію.",
|
||||||
"The device ID cannot be blank.": "ID пристрою не може бути порожнім.",
|
"The device ID cannot be blank.": "ID пристрою не може бути порожнім.",
|
||||||
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).",
|
"The device ID to enter here can be found in the \"Actions > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "ID пристрою, який необхідно додати. Може бути знайдений у вікні \"Редагувати > Показати ID\" на іншому пристрої. Пробіли та тире опціональні (будуть видалені програмою).",
|
||||||
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "ID пристрою, який необхідно додати. Може бути знайдений у вікні \"Редагувати > Показати ID\" на іншому пристрої. Пробіли та тире опціональні (вони ігноруються програмою).",
|
"The device ID to enter here can be found in the \"Edit > Show ID\" dialog on the other device. Spaces and dashes are optional (ignored).": "ID пристрою, який необхідно додати. Може бути знайдений у вікні \"Редагувати > Показати ID\" на іншому пристрої. Пробіли та тире опціональні (вони ігноруються програмою).",
|
||||||
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "Зашифрована статистика використання відсилається щоденно. Вона використовується для того, щоб розробники розуміли, на яких платформах працює програма, розміри директорій та версії програми. Якщо набір даних, що збирається зазнає змін, ви обов’язково будете повідомлені через це діалогове вікно.",
|
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "Зашифрована статистика використання відсилається щоденно. Вона використовується для того, щоб розробники розуміли, на яких платформах працює програма, розміри директорій та версії програми. Якщо набір даних, що збирається зазнає змін, ви обов’язково будете повідомлені через це діалогове вікно.",
|
||||||
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "Введений ID пристрою невалідний. Ідентифікатор має вигляд строки довжиною 52 або 56 символів, що містить цифри та літери, із опціональними пробілами та тире.",
|
"The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.": "Введений ID пристрою невалідний. Ідентифікатор має вигляд строки довжиною 52 або 56 символів, що містить цифри та літери, із опціональними пробілами та тире.",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "Швидкість має бути додатнім числом.",
|
"The rate limit must be a non-negative number (0: no limit)": "Швидкість має бути додатнім числом.",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Інтервал повторного сканування повинен бути неід’ємною величиною.",
|
"The rescan interval must be a non-negative number of seconds.": "Інтервал повторного сканування повинен бути неід’ємною величиною.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Вони будуть автоматично повторно синхронізовані, коли помилку буде усунено. ",
|
"They are retried automatically and will be synced when the error is resolved.": "Вони будуть автоматично повторно синхронізовані, коли помилку буде усунено. ",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Це легко може дати хакерам доступ до читання та зміни будь-яких файлів на вашому комп'ютері.",
|
"This can easily give hackers access to read and change any files on your computer.": "Це легко може дати хакерам доступ до читання та зміни будь-яких файлів на вашому комп'ютері.",
|
||||||
"This is a major version upgrade.": "Це оновлення мажорної версії",
|
"This is a major version upgrade.": "Це оновлення мажорної версії",
|
||||||
"Trash Can File Versioning": "Версіонування файлів у кошику ",
|
"Trash Can File Versioning": "Версіонування файлів у кошику ",
|
||||||
@@ -220,12 +228,14 @@
|
|||||||
"Version": "Версія",
|
"Version": "Версія",
|
||||||
"Versions Path": "Шлях до версій",
|
"Versions Path": "Шлях до версій",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Версії автоматично видаляються, якщо вони старше, ніж максимальний вік, або перевищують допустиму кількість файлів за інтервал.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Версії автоматично видаляються, якщо вони старше, ніж максимальний вік, або перевищують допустиму кількість файлів за інтервал.",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Коли додаєте новий пристрій, пам’ятайте, що цей пристрій повинен бути доданий і на іншій стороні.",
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Коли додаєте нову директорію, пам’ятайте, що ID цієї директорії використовується для того, щоб зв’язувати директорії разом між вузлами. Назви є чутливими до регістра та повинні співпадати точно між усіма вузлами.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Коли додаєте новий вузол, пам’ятайте, що цей вузол повинен бути доданий і на іншій стороні.",
|
||||||
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Коли додаєте нову директорію, пам’ятайте, що ID цієї директорії використовується для того, щоб зв’язувати директорії разом між пристроями. Назви повинні точно співпадати між усіма пристроями, регістр символів має значення.",
|
||||||
"Yes": "Так",
|
"Yes": "Так",
|
||||||
"You must keep at least one version.": "Ви повинні зберігати щонайменше одну версію.",
|
"You must keep at least one version.": "Ви повинні зберігати щонайменше одну версію.",
|
||||||
"days": "днів",
|
"days": "днів",
|
||||||
"full documentation": "повна документація",
|
"full documentation": "повна документація",
|
||||||
"items": "елементи",
|
"items": "елементи",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} хоче поділитися директорією \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} хоче поділитися директорією \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "Thêm",
|
"Add": "Thêm",
|
||||||
"Add Device": "Thêm thiết bị",
|
"Add Device": "Thêm thiết bị",
|
||||||
"Add Folder": "Thêm thư mục",
|
"Add Folder": "Thêm thư mục",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "Thêm thư mục mới?",
|
"Add new folder?": "Thêm thư mục mới?",
|
||||||
"Address": "Địa chỉ",
|
"Address": "Địa chỉ",
|
||||||
"Addresses": "Các địa chỉ",
|
"Addresses": "Các địa chỉ",
|
||||||
"Advanced": "Nâng cao",
|
"Advanced": "Nâng cao",
|
||||||
"Advanced Configuration": "Cấu hình nâng cao",
|
"Advanced Configuration": "Cấu hình nâng cao",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "Tất cả dữ liệu",
|
"All Data": "Tất cả dữ liệu",
|
||||||
"Allow Anonymous Usage Reporting?": "Cho phép báo cáo sử dụng ẩn danh?",
|
"Allow Anonymous Usage Reporting?": "Cho phép báo cáo sử dụng ẩn danh?",
|
||||||
"Alphabetic": "A-Z",
|
"Alphabetic": "A-Z",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "Lỗi kết nối",
|
"Connection Error": "Lỗi kết nối",
|
||||||
"Copied from elsewhere": "Đã sao chép từ nơi khác",
|
"Copied from elsewhere": "Đã sao chép từ nơi khác",
|
||||||
"Copied from original": "Đã sao chép từ nguồn",
|
"Copied from original": "Đã sao chép từ nguồn",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Bản quyền © 2015 thuộc về các nhà cộng tác sau:",
|
"Copyright © 2015 the following Contributors:": "Bản quyền © 2015 thuộc về các nhà cộng tác sau:",
|
||||||
"Danger!": "Nguy hiểm!",
|
"Danger!": "Nguy hiểm!",
|
||||||
"Delete": "Xoá",
|
"Delete": "Xoá",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Các tập tin sẽ được bảo vệ khỏi những thay đổi trên các thiết bị khác, nhưng những thay đổi trên thiết bị này sẽ được chuyển tới các máy còn lại trong cụm.",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Các tập tin sẽ được bảo vệ khỏi những thay đổi trên các thiết bị khác, nhưng những thay đổi trên thiết bị này sẽ được chuyển tới các máy còn lại trong cụm.",
|
||||||
"Folder": "Thư mục",
|
"Folder": "Thư mục",
|
||||||
"Folder ID": "ID thư mục",
|
"Folder ID": "ID thư mục",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "Thư mục Chủ",
|
"Folder Master": "Thư mục Chủ",
|
||||||
"Folder Path": "Đường dẫn đến thư mục",
|
"Folder Path": "Đường dẫn đến thư mục",
|
||||||
"Folders": "Các thư mục",
|
"Folders": "Các thư mục",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Off": "Tắt",
|
"Off": "Tắt",
|
||||||
"Oldest First": "Cũ nhất đầu tiên",
|
"Oldest First": "Cũ nhất đầu tiên",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "Tuỳ chọn",
|
"Options": "Tuỳ chọn",
|
||||||
"Out of Sync": "Mất đồng bộ",
|
"Out of Sync": "Mất đồng bộ",
|
||||||
"Out of Sync Items": "Các nội dung mất đồng bộ",
|
"Out of Sync Items": "Các nội dung mất đồng bộ",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "Chuyển tiếp qua",
|
"Relayed via": "Chuyển tiếp qua",
|
||||||
"Relays": "Các máy chuyển tiếp",
|
"Relays": "Các máy chuyển tiếp",
|
||||||
"Release Notes": "Lịch sử phát hành",
|
"Release Notes": "Lịch sử phát hành",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "Xoá",
|
"Remove": "Xoá",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "Quét lại",
|
"Rescan": "Quét lại",
|
||||||
"Rescan All": "Quét lại tất cả",
|
"Rescan All": "Quét lại tất cả",
|
||||||
"Rescan Interval": "Khoảng cách thời gian quét lại",
|
"Rescan Interval": "Khoảng cách thời gian quét lại",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "Giới hạn tốc độ phải là một số không âm (0: không giới hạn)",
|
"The rate limit must be a non-negative number (0: no limit)": "Giới hạn tốc độ phải là một số không âm (0: không giới hạn)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "Khoảng thời gian quét lại phải là một số giây không âm.",
|
"The rescan interval must be a non-negative number of seconds.": "Khoảng thời gian quét lại phải là một số giây không âm.",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "Chúng sẽ được tự động thử lại và đồng bộ khi lỗi được khắc phục.",
|
"They are retried automatically and will be synced when the error is resolved.": "Chúng sẽ được tự động thử lại và đồng bộ khi lỗi được khắc phục.",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "Thao tác này có thể khiến tin tặc truy cập để đọc và thay đổi bất kỳ tập tin nào trên máy tính của bạn một cách dễ dàng.",
|
"This can easily give hackers access to read and change any files on your computer.": "Thao tác này có thể khiến tin tặc truy cập để đọc và thay đổi bất kỳ tập tin nào trên máy tính của bạn một cách dễ dàng.",
|
||||||
"This is a major version upgrade.": "Đây là bản nâng cấp quan trọng.",
|
"This is a major version upgrade.": "Đây là bản nâng cấp quan trọng.",
|
||||||
"Trash Can File Versioning": "Kiểu thùng rác",
|
"Trash Can File Versioning": "Kiểu thùng rác",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "Phiên bản",
|
"Version": "Phiên bản",
|
||||||
"Versions Path": "Đường dẫn đến các phiên bản",
|
"Versions Path": "Đường dẫn đến các phiên bản",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Các phiên bản sẽ tự động được xoá nếu chúng cũ hơn thời hạn tối đa hoặc vượt quá số tập tin cho phép trong một khoảng thời gian.",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Các phiên bản sẽ tự động được xoá nếu chúng cũ hơn thời hạn tối đa hoặc vượt quá số tập tin cho phép trong một khoảng thời gian.",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "Khi thêm một thiết bị mới, hãy nhớ rằng thiết bị này cũng phải được thêm vào máy kia.",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "Khi thêm một thiết bị mới, hãy nhớ rằng thiết bị này cũng phải được thêm vào máy kia.",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Khi thêm một thư mục mới, hãy nhớ rằng ID thư mục được dùng để gắn kết thư mục giữa các thiết bị với nhau. Chúng phải chính xác từng chữ, cả viết hoa và thường giữa tất cả thiết bị.",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "Khi thêm một thư mục mới, hãy nhớ rằng ID thư mục được dùng để gắn kết thư mục giữa các thiết bị với nhau. Chúng phải chính xác từng chữ, cả viết hoa và thường giữa tất cả thiết bị.",
|
||||||
"Yes": "Phải",
|
"Yes": "Phải",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "ngày",
|
"days": "ngày",
|
||||||
"full documentation": "tài liệu đầy đủ",
|
"full documentation": "tài liệu đầy đủ",
|
||||||
"items": "nội dung",
|
"items": "nội dung",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} muốn chia sẻ thư mục \"{{folder}}\"."
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} muốn chia sẻ thư mục \"{{folder}}\".",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "添加",
|
"Add": "添加",
|
||||||
"Add Device": "添加设备",
|
"Add Device": "添加设备",
|
||||||
"Add Folder": "添加文件夹",
|
"Add Folder": "添加文件夹",
|
||||||
|
"Add Remote Device": "添加远程设备",
|
||||||
"Add new folder?": "添加新文件夹?",
|
"Add new folder?": "添加新文件夹?",
|
||||||
"Address": "地址",
|
"Address": "地址",
|
||||||
"Addresses": "地址列表",
|
"Addresses": "地址列表",
|
||||||
"Advanced": "高级",
|
"Advanced": "高级",
|
||||||
"Advanced Configuration": "高级设置",
|
"Advanced Configuration": "高级设置",
|
||||||
|
"Advanced settings": "高级设置",
|
||||||
"All Data": "所有数据",
|
"All Data": "所有数据",
|
||||||
"Allow Anonymous Usage Reporting?": "允许匿名使用报告?",
|
"Allow Anonymous Usage Reporting?": "允许匿名使用报告?",
|
||||||
"Alphabetic": "字母顺序",
|
"Alphabetic": "字母顺序",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "连接出错",
|
"Connection Error": "连接出错",
|
||||||
"Copied from elsewhere": "从其他设备复制",
|
"Copied from elsewhere": "从其他设备复制",
|
||||||
"Copied from original": "从源复制",
|
"Copied from original": "从源复制",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "版权所有© 2014-2016 以下贡献者:",
|
||||||
"Copyright © 2015 the following Contributors:": "版权 ©2015 由下列贡献者所有:",
|
"Copyright © 2015 the following Contributors:": "版权 ©2015 由下列贡献者所有:",
|
||||||
"Danger!": "危险!",
|
"Danger!": "危险!",
|
||||||
"Delete": "删除",
|
"Delete": "删除",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "在其它设备中对该文件夹内文件的修改并不会被同步到本机,但是在本机上对其的修改,则会被同步到其它设备中。",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "在其它设备中对该文件夹内文件的修改并不会被同步到本机,但是在本机上对其的修改,则会被同步到其它设备中。",
|
||||||
"Folder": "文件夹",
|
"Folder": "文件夹",
|
||||||
"Folder ID": "文件夹标识",
|
"Folder ID": "文件夹标识",
|
||||||
|
"Folder Label": "文件夹标签",
|
||||||
"Folder Master": "主文件夹",
|
"Folder Master": "主文件夹",
|
||||||
"Folder Path": "文件夹路径",
|
"Folder Path": "文件夹路径",
|
||||||
"Folders": "文件夹",
|
"Folders": "文件夹",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "确定",
|
"OK": "确定",
|
||||||
"Off": "关闭",
|
"Off": "关闭",
|
||||||
"Oldest First": "旧文件优先",
|
"Oldest First": "旧文件优先",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "可选的文件夹表述标签。在不同设备上可以不一致。",
|
||||||
"Options": "选项",
|
"Options": "选项",
|
||||||
"Out of Sync": "未同步",
|
"Out of Sync": "未同步",
|
||||||
"Out of Sync Items": "未同步的项目",
|
"Out of Sync Items": "未同步的项目",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "中转经由",
|
"Relayed via": "中转经由",
|
||||||
"Relays": "中转",
|
"Relays": "中转",
|
||||||
"Release Notes": "发布说明",
|
"Release Notes": "发布说明",
|
||||||
|
"Remote Devices": "远程设备",
|
||||||
"Remove": "移除",
|
"Remove": "移除",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "需要给文件夹设置标识。在所有丛设备上必须一致。",
|
||||||
"Rescan": "重新扫描",
|
"Rescan": "重新扫描",
|
||||||
"Rescan All": "全部重新扫描",
|
"Rescan All": "全部重新扫描",
|
||||||
"Rescan Interval": "扫描间隔",
|
"Rescan Interval": "扫描间隔",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "传输速度限制为非负整数(0 表示不限制)",
|
"The rate limit must be a non-negative number (0: no limit)": "传输速度限制为非负整数(0 表示不限制)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "扫描间隔单位为秒,且不能为负数。",
|
"The rescan interval must be a non-negative number of seconds.": "扫描间隔单位为秒,且不能为负数。",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "系统将会自动重试,当错误被解决时,它们将会被同步。",
|
"They are retried automatically and will be synced when the error is resolved.": "系统将会自动重试,当错误被解决时,它们将会被同步。",
|
||||||
|
"This Device": "当前设备",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "这会让骇客能够轻而易举地访问及修改您的文件",
|
"This can easily give hackers access to read and change any files on your computer.": "这会让骇客能够轻而易举地访问及修改您的文件",
|
||||||
"This is a major version upgrade.": "这是一个重大版本更新",
|
"This is a major version upgrade.": "这是一个重大版本更新",
|
||||||
"Trash Can File Versioning": "回收站式版本控制",
|
"Trash Can File Versioning": "回收站式版本控制",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "版本",
|
"Version": "版本",
|
||||||
"Versions Path": "历史版本路径",
|
"Versions Path": "历史版本路径",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "超过最长保留时间,或者不满足下列条件的历史版本,将会被删除。",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "超过最长保留时间,或者不满足下列条件的历史版本,将会被删除。",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "警告, 该路径是一个已经存在文件夹\"{{otherFolder}}\"的子文件夹.",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "若您在本机添加新设备,记住您也必须在这个设备上添加本机。",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "若您在本机添加新设备,记住您也必须在这个设备上添加本机。",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "若你添加了新文件夹,记住文件夹标识是用以在不同设备间建立联系的。在不同设备间拥有相同标识的文件夹将会被同步。且文件夹标识大小写敏感。",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "若你添加了新文件夹,记住文件夹标识是用以在不同设备间建立联系的。在不同设备间拥有相同标识的文件夹将会被同步。且文件夹标识大小写敏感。",
|
||||||
"Yes": "是",
|
"Yes": "是",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "天",
|
"days": "天",
|
||||||
"full documentation": "完整文档",
|
"full documentation": "完整文档",
|
||||||
"items": "条目",
|
"items": "条目",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} 想将 “{{folder}}” 文件夹共享给您"
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} 想将 “{{folder}}” 文件夹共享给您",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}}想要分享文件夹\"{{folderLabel}}\" ({{folder}}).\n"
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,13 @@
|
|||||||
"Add": "增加",
|
"Add": "增加",
|
||||||
"Add Device": "增加裝置",
|
"Add Device": "增加裝置",
|
||||||
"Add Folder": "增加資料夾",
|
"Add Folder": "增加資料夾",
|
||||||
|
"Add Remote Device": "Add Remote Device",
|
||||||
"Add new folder?": "新增資料夾?",
|
"Add new folder?": "新增資料夾?",
|
||||||
"Address": "位址",
|
"Address": "位址",
|
||||||
"Addresses": "位址",
|
"Addresses": "位址",
|
||||||
"Advanced": "進階",
|
"Advanced": "進階",
|
||||||
"Advanced Configuration": "進階設定",
|
"Advanced Configuration": "進階設定",
|
||||||
|
"Advanced settings": "Advanced settings",
|
||||||
"All Data": "全部資料",
|
"All Data": "全部資料",
|
||||||
"Allow Anonymous Usage Reporting?": "允許匿名的使用資訊回報?",
|
"Allow Anonymous Usage Reporting?": "允許匿名的使用資訊回報?",
|
||||||
"Alphabetic": "字母順序",
|
"Alphabetic": "字母順序",
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"Connection Error": "連線錯誤",
|
"Connection Error": "連線錯誤",
|
||||||
"Copied from elsewhere": "從別處複製",
|
"Copied from elsewhere": "從別處複製",
|
||||||
"Copied from original": "從原來複製",
|
"Copied from original": "從原來複製",
|
||||||
|
"Copyright © 2014-2016 the following Contributors:": "Copyright © 2014-2016 the following Contributors:",
|
||||||
"Copyright © 2015 the following Contributors:": "Copyright © 2015 下列貢獻者:",
|
"Copyright © 2015 the following Contributors:": "Copyright © 2015 下列貢獻者:",
|
||||||
"Danger!": "Danger!",
|
"Danger!": "Danger!",
|
||||||
"Delete": "刪除",
|
"Delete": "刪除",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "其他裝置做的改變不會影響到此裝置的檔案,但在此裝置上的變化將被發送到叢集中的其他部分。",
|
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "其他裝置做的改變不會影響到此裝置的檔案,但在此裝置上的變化將被發送到叢集中的其他部分。",
|
||||||
"Folder": "資料夾",
|
"Folder": "資料夾",
|
||||||
"Folder ID": "資料夾識別碼",
|
"Folder ID": "資料夾識別碼",
|
||||||
|
"Folder Label": "Folder Label",
|
||||||
"Folder Master": "主資料夾",
|
"Folder Master": "主資料夾",
|
||||||
"Folder Path": "資料夾路徑",
|
"Folder Path": "資料夾路徑",
|
||||||
"Folders": "資料夾",
|
"Folders": "資料夾",
|
||||||
@@ -111,6 +115,7 @@
|
|||||||
"OK": "確定",
|
"OK": "確定",
|
||||||
"Off": "關閉",
|
"Off": "關閉",
|
||||||
"Oldest First": "最舊的優先",
|
"Oldest First": "最舊的優先",
|
||||||
|
"Optional descriptive label for the folder. Can be different on each device.": "Optional descriptive label for the folder. Can be different on each device.",
|
||||||
"Options": "選項",
|
"Options": "選項",
|
||||||
"Out of Sync": "Out of Sync",
|
"Out of Sync": "Out of Sync",
|
||||||
"Out of Sync Items": "不同步物件",
|
"Out of Sync Items": "不同步物件",
|
||||||
@@ -132,7 +137,9 @@
|
|||||||
"Relayed via": "中繼於",
|
"Relayed via": "中繼於",
|
||||||
"Relays": "中繼點",
|
"Relays": "中繼點",
|
||||||
"Release Notes": "版本資訊",
|
"Release Notes": "版本資訊",
|
||||||
|
"Remote Devices": "Remote Devices",
|
||||||
"Remove": "移除",
|
"Remove": "移除",
|
||||||
|
"Required identifier for the folder. Must be the same on all cluster devices.": "Required identifier for the folder. Must be the same on all cluster devices.",
|
||||||
"Rescan": "重新掃描",
|
"Rescan": "重新掃描",
|
||||||
"Rescan All": "全部重新掃描",
|
"Rescan All": "全部重新掃描",
|
||||||
"Rescan Interval": "重新掃描間隔",
|
"Rescan Interval": "重新掃描間隔",
|
||||||
@@ -203,6 +210,7 @@
|
|||||||
"The rate limit must be a non-negative number (0: no limit)": "限制速率必須為非負的數字 (0: 不設限制)",
|
"The rate limit must be a non-negative number (0: no limit)": "限制速率必須為非負的數字 (0: 不設限制)",
|
||||||
"The rescan interval must be a non-negative number of seconds.": "重新掃描間隔必須為一個非負數的秒數。",
|
"The rescan interval must be a non-negative number of seconds.": "重新掃描間隔必須為一個非負數的秒數。",
|
||||||
"They are retried automatically and will be synced when the error is resolved.": "解決間題後,將會自動重試和同步。",
|
"They are retried automatically and will be synced when the error is resolved.": "解決間題後,將會自動重試和同步。",
|
||||||
|
"This Device": "This Device",
|
||||||
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
||||||
"This is a major version upgrade.": "這是一個主要版本更新。",
|
"This is a major version upgrade.": "這是一個主要版本更新。",
|
||||||
"Trash Can File Versioning": "Trash Can File Versioning",
|
"Trash Can File Versioning": "Trash Can File Versioning",
|
||||||
@@ -220,6 +228,7 @@
|
|||||||
"Version": "版本",
|
"Version": "版本",
|
||||||
"Versions Path": "歷史版本路徑",
|
"Versions Path": "歷史版本路徑",
|
||||||
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "當檔案歷史版本的存留時間大於設定的最大值,或是其數量在一段時間內超出允許值時,則會被刪除。",
|
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "當檔案歷史版本的存留時間大於設定的最大值,或是其數量在一段時間內超出允許值時,則會被刪除。",
|
||||||
|
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Warning, this path is a subdirectory of an existing folder \"{{otherFolder}}\".",
|
||||||
"When adding a new device, keep in mind that this device must be added on the other side too.": "當新增一個裝置時,務必記住,當前的這個裝置也同樣必須被添加至另一邊。",
|
"When adding a new device, keep in mind that this device must be added on the other side too.": "當新增一個裝置時,務必記住,當前的這個裝置也同樣必須被添加至另一邊。",
|
||||||
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "當新增一個資料夾時,請記住,資料夾識別碼是用來將裝置之間的資料夾綁定在一起的。它們有區分大小寫,且必須在所有裝置之間完全相同。",
|
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "當新增一個資料夾時,請記住,資料夾識別碼是用來將裝置之間的資料夾綁定在一起的。它們有區分大小寫,且必須在所有裝置之間完全相同。",
|
||||||
"Yes": "是",
|
"Yes": "是",
|
||||||
@@ -227,5 +236,6 @@
|
|||||||
"days": "日",
|
"days": "日",
|
||||||
"full documentation": "完整說明文件",
|
"full documentation": "完整說明文件",
|
||||||
"items": "個項目",
|
"items": "個項目",
|
||||||
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} 想要分享資料夾 \"{{folder}}\"。"
|
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} 想要分享資料夾 \"{{folder}}\"。",
|
||||||
|
"{%device%} wants to share folder \"{%folderLabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderLabel}}\" ({{folder}})."
|
||||||
}
|
}
|
||||||
@@ -1 +1 @@
|
|||||||
var langPrettyprint = {"bg":"Bulgarian","ca":"Catalan","ca@valencia":"Catalan (Valencian)","cs":"Czech","da":"Danish","de":"German","el":"Greek","en":"English","en-GB":"English (United Kingdom)","es":"Spanish","es-ES":"Spanish (Spain)","fi":"Finnish","fr":"French","fr-CA":"French (Canada)","fy":"Western Frisian","hu":"Hungarian","id":"Indonesian","it":"Italian","ja":"Japanese","ko-KR":"Korean (Korea)","lt":"Lithuanian","nb":"Norwegian Bokmål","nl":"Dutch","nn":"Norwegian Nynorsk","pl":"Polish","pt-BR":"Portuguese (Brazil)","pt-PT":"Portuguese (Portugal)","ro-RO":"Romanian (Romania)","ru":"Russian","sv":"Swedish","tr":"Turkish","uk":"Ukrainian","vi":"Vietnamese","zh-CN":"Chinese (China)","zh-TW":"Chinese (Taiwan)"}
|
var langPrettyprint = {"bg":"Bulgarian","ca":"Catalan","ca@valencia":"Catalan (Valencian)","cs":"Czech","da":"Danish","de":"German","el":"Greek","en":"English","en-GB":"English (United Kingdom)","es":"Spanish","es-ES":"Spanish (Spain)","fi":"Finnish","fr":"French","fr-CA":"French (Canada)","fy":"Western Frisian","hu":"Hungarian","id":"Indonesian","it":"Italian","ja":"Japanese","ko-KR":"Korean (Korea)","lt":"Lithuanian","nb":"Norwegian Bokmål","nl":"Dutch","nn":"Norwegian Nynorsk","pl":"Polish","pt-BR":"Portuguese (Brazil)","pt-PT":"Portuguese (Portugal)","ru":"Russian","sv":"Swedish","tr":"Turkish","uk":"Ukrainian","vi":"Vietnamese","zh-CN":"Chinese (China)","zh-TW":"Chinese (Taiwan)"}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
var validLangs = ["bg","ca","ca@valencia","cs","da","de","el","en","en-GB","es","es-ES","fi","fr","fr-CA","fy","hu","id","it","ja","ko-KR","lt","nb","nl","nn","pl","pt-BR","pt-PT","ro-RO","ru","sv","tr","uk","vi","zh-CN","zh-TW"]
|
var validLangs = ["bg","ca","ca@valencia","cs","da","de","el","en","en-GB","es","es-ES","fi","fr","fr-CA","fy","hu","id","it","ja","ko-KR","lt","nb","nl","nn","pl","pt-BR","pt-PT","ru","sv","tr","uk","vi","zh-CN","zh-TW"]
|
||||||
|
|||||||
+14
-13
@@ -221,8 +221,9 @@
|
|||||||
<div class="panel-heading" data-toggle="collapse" data-parent="#folders" href="#folder-{{$index}}" style="cursor: pointer">
|
<div class="panel-heading" data-toggle="collapse" data-parent="#folders" href="#folder-{{$index}}" style="cursor: pointer">
|
||||||
<div class="panel-progress" ng-show="folderStatus(folder) == 'syncing'" ng-attr-style="width: {{syncPercentage(folder.id)}}%"></div>
|
<div class="panel-progress" ng-show="folderStatus(folder) == 'syncing'" ng-attr-style="width: {{syncPercentage(folder.id)}}%"></div>
|
||||||
<div class="panel-progress" ng-show="folderStatus(folder) == 'scanning' && scanProgress[folder.id] != undefined" ng-attr-style="width: {{scanPercentage(folder.id)}}%"></div>
|
<div class="panel-progress" ng-show="folderStatus(folder) == 'scanning' && scanProgress[folder.id] != undefined" ng-attr-style="width: {{scanPercentage(folder.id)}}%"></div>
|
||||||
<h3 class="panel-title">
|
<h4 class="panel-title">
|
||||||
<span class="fa fa-folder hidden-xs"></span>{{folder.id}}
|
<span class="fa hidden-xs fa-fw" ng-class="[folder.readOnly ? 'fa-lock' : 'fa-folder']"></span>
|
||||||
|
<a href="#folder-{{$index}}">{{folder.id}}</a>
|
||||||
<span class="pull-right text-{{folderClass(folder)}}" ng-switch="folderStatus(folder)">
|
<span class="pull-right text-{{folderClass(folder)}}" ng-switch="folderStatus(folder)">
|
||||||
<span ng-switch-when="unknown"><span class="hidden-xs" translate>Unknown</span><span class="visible-xs">◼</span></span>
|
<span ng-switch-when="unknown"><span class="hidden-xs" translate>Unknown</span><span class="visible-xs">◼</span></span>
|
||||||
<span ng-switch-when="unshared"><span class="hidden-xs" translate>Unshared</span><span class="visible-xs">◼</span></span>
|
<span ng-switch-when="unshared"><span class="hidden-xs" translate>Unshared</span><span class="visible-xs">◼</span></span>
|
||||||
@@ -241,7 +242,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<span ng-switch-when="outofsync"><span class="hidden-xs" translate>Out of Sync</span><span class="visible-xs">◼</span></span>
|
<span ng-switch-when="outofsync"><span class="hidden-xs" translate>Out of Sync</span><span class="visible-xs">◼</span></span>
|
||||||
</span>
|
</span>
|
||||||
</h3>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div id="folder-{{$index}}" class="panel-collapse collapse">
|
<div id="folder-{{$index}}" class="panel-collapse collapse">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
@@ -249,7 +250,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th><span class="fa fa-fw fa-folder-open"></span> <span translate>Folder Path</span></th>
|
<th><span class="fa fa-fw fa-folder-open"></span> <span translate>Folder Path</span></th>
|
||||||
<td class="text-right">{{folder.path}}</td>
|
<td class="text-right" title="{{folder.path}}">{{folder.path}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr ng-if="model[folder.id].invalid || model[folder.id].error">
|
<tr ng-if="model[folder.id].invalid || model[folder.id].error">
|
||||||
<th><span class="fa fa-fw fa-exclamation-triangle"></span> <span translate>Error</span></th>
|
<th><span class="fa fa-fw fa-exclamation-triangle"></span> <span translate>Error</span></th>
|
||||||
@@ -379,12 +380,12 @@
|
|||||||
<!-- This device -->
|
<!-- This device -->
|
||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<h3 translate>Devices</h3>
|
<h3 translate>This Device</h3>
|
||||||
<div class="panel panel-default" ng-repeat="deviceCfg in [thisDevice()]">
|
<div class="panel panel-default" ng-repeat="deviceCfg in [thisDevice()]">
|
||||||
<div class="panel-heading" data-toggle="collapse" href="#device-this" style="cursor: pointer">
|
<div class="panel-heading" data-toggle="collapse" href="#device-this" style="cursor: pointer">
|
||||||
<h3 class="panel-title">
|
<h4 class="panel-title">
|
||||||
<identicon data-value="deviceCfg.deviceID"></identicon> {{deviceName(deviceCfg)}}
|
<identicon data-value="deviceCfg.deviceID"></identicon> {{deviceName(deviceCfg)}}
|
||||||
</h3>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div id="device-this" class="panel-collapse collapse in">
|
<div id="device-this" class="panel-collapse collapse in">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
@@ -442,7 +443,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th><span class="fa fa-fw fa-tag"></span> <span translate>Version</span></th>
|
<th><span class="fa fa-fw fa-tag"></span> <span translate>Version</span></th>
|
||||||
<td class="text-right">{{versionString()}}</td>
|
<td class="text-right" title="{{versionString()}}">{{versionString()}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -451,13 +452,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Remote devices -->
|
<!-- Remote devices -->
|
||||||
|
<h3 translate>Remote Devices</h3>
|
||||||
<div class="panel-group" id="devices">
|
<div class="panel-group" id="devices">
|
||||||
<div class="panel panel-default" ng-repeat="deviceCfg in otherDevices()">
|
<div class="panel panel-default" ng-repeat="deviceCfg in otherDevices()">
|
||||||
<div class="panel-heading" data-toggle="collapse" data-parent="#devices" href="#device-{{$index}}" style="cursor: pointer">
|
<div class="panel-heading" data-toggle="collapse" data-parent="#devices" href="#device-{{$index}}" style="cursor: pointer">
|
||||||
<div class="panel-progress" ng-show="deviceStatus(deviceCfg) == 'syncing'" ng-attr-style="width: {{completion[deviceCfg.deviceID]._total | number:0}}%"></div>
|
<div class="panel-progress" ng-show="deviceStatus(deviceCfg) == 'syncing'" ng-attr-style="width: {{completion[deviceCfg.deviceID]._total | number:0}}%"></div>
|
||||||
<h3 class="panel-title">
|
<h4 class="panel-title">
|
||||||
<identicon data-value="deviceCfg.deviceID"></identicon> {{deviceName(deviceCfg)}}
|
<identicon data-value="deviceCfg.deviceID"></identicon> <a href="#device-{{$index}}">{{deviceName(deviceCfg)}}</a>
|
||||||
<span ng-switch="deviceStatus(deviceCfg)" class="pull-right text-{{deviceClass(deviceCfg)}}">
|
<span ng-switch="deviceStatus(deviceCfg)" class="pull-right text-{{deviceClass(deviceCfg)}}">
|
||||||
<span ng-switch-when="insync"><span class="hidden-xs" translate>Up to Date</span><span class="visible-xs">◼</span></span>
|
<span ng-switch-when="insync"><span class="hidden-xs" translate>Up to Date</span><span class="visible-xs">◼</span></span>
|
||||||
<span ng-switch-when="syncing">
|
<span ng-switch-when="syncing">
|
||||||
@@ -467,7 +468,7 @@
|
|||||||
<span ng-switch-when="disconnected"><span class="hidden-xs" translate>Disconnected</span><span class="visible-xs">◼</span></span>
|
<span ng-switch-when="disconnected"><span class="hidden-xs" translate>Disconnected</span><span class="visible-xs">◼</span></span>
|
||||||
<span ng-switch-when="unused"><span class="hidden-xs" translate>Unused</span><span class="visible-xs">◼</span></span>
|
<span ng-switch-when="unused"><span class="hidden-xs" translate>Unused</span><span class="visible-xs">◼</span></span>
|
||||||
</span>
|
</span>
|
||||||
</h3>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div id="device-{{$index}}" class="panel-collapse collapse">
|
<div id="device-{{$index}}" class="panel-collapse collapse">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
@@ -535,7 +536,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button type="button" class="btn btn-sm btn-default pull-right" ng-click="addDevice()">
|
<button type="button" class="btn btn-sm btn-default pull-right" ng-click="addDevice()">
|
||||||
<span class="fa fa-plus"></span> <span translate>Add Device</span>
|
<span class="fa fa-plus"></span> <span translate>Add Remote Device</span>
|
||||||
</button>
|
</button>
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -69,6 +69,7 @@
|
|||||||
<li class="auto-generated">Marcin Dziadus</li>
|
<li class="auto-generated">Marcin Dziadus</li>
|
||||||
<li class="auto-generated">Mateusz Naściszewski</li>
|
<li class="auto-generated">Mateusz Naściszewski</li>
|
||||||
<li class="auto-generated">Matt Burke</li>
|
<li class="auto-generated">Matt Burke</li>
|
||||||
|
<li class="auto-generated">Max Schulze</li>
|
||||||
<li class="auto-generated">Michael Jephcote</li>
|
<li class="auto-generated">Michael Jephcote</li>
|
||||||
<li class="auto-generated">Michael Ploujnikov</li>
|
<li class="auto-generated">Michael Ploujnikov</li>
|
||||||
<li class="auto-generated">Michael Tilli</li>
|
<li class="auto-generated">Michael Tilli</li>
|
||||||
@@ -92,6 +93,7 @@
|
|||||||
<li class="auto-generated">Victor Buinsky</li>
|
<li class="auto-generated">Victor Buinsky</li>
|
||||||
<li class="auto-generated">Vil Brekin</li>
|
<li class="auto-generated">Vil Brekin</li>
|
||||||
<li class="auto-generated">William A. Kennington III</li>
|
<li class="auto-generated">William A. Kennington III</li>
|
||||||
|
<li class="auto-generated">Wulf Weich</li>
|
||||||
<li class="auto-generated">Yannic A.</li>
|
<li class="auto-generated">Yannic A.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+42
-43
File diff suppressed because one or more lines are too long
@@ -1,2 +1 @@
|
|||||||
!*.zip
|
|
||||||
testdata/*.db
|
testdata/*.db
|
||||||
|
|||||||
+33
-20
@@ -4,9 +4,16 @@
|
|||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
// Package db provides a set type to track local/remote files with newness
|
||||||
|
// checks. We must do a certain amount of normalization in here. We will get
|
||||||
|
// fed paths with either native or wire-format separators and encodings
|
||||||
|
// depending on who calls us. We transform paths to wire-format (NFC and
|
||||||
|
// slashes) on the way to the database, and transform to native format
|
||||||
|
// (varying separator and encoding) on the way back out.
|
||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
@@ -23,10 +30,10 @@ const maxBatchSize = 256 << 10
|
|||||||
|
|
||||||
type BlockMap struct {
|
type BlockMap struct {
|
||||||
db *Instance
|
db *Instance
|
||||||
folder uint32
|
folder string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBlockMap(db *Instance, folder uint32) *BlockMap {
|
func NewBlockMap(db *Instance, folder string) *BlockMap {
|
||||||
return &BlockMap{
|
return &BlockMap{
|
||||||
db: db,
|
db: db,
|
||||||
folder: folder,
|
folder: folder,
|
||||||
@@ -116,7 +123,7 @@ func (m *BlockMap) Discard(files []protocol.FileInfo) error {
|
|||||||
// Drop block map, removing all entries related to this block map from the db.
|
// Drop block map, removing all entries related to this block map from the db.
|
||||||
func (m *BlockMap) Drop() error {
|
func (m *BlockMap) Drop() error {
|
||||||
batch := new(leveldb.Batch)
|
batch := new(leveldb.Batch)
|
||||||
iter := m.db.NewIterator(util.BytesPrefix(m.blockKeyInto(nil, nil, "")[:keyPrefixLen+keyFolderLen]), nil)
|
iter := m.db.NewIterator(util.BytesPrefix(m.blockKeyInto(nil, nil, "")[:1+64]), nil)
|
||||||
defer iter.Release()
|
defer iter.Release()
|
||||||
for iter.Next() {
|
for iter.Next() {
|
||||||
if batch.Len() > maxBatchSize {
|
if batch.Len() > maxBatchSize {
|
||||||
@@ -166,13 +173,12 @@ func (f *BlockFinder) String() string {
|
|||||||
func (f *BlockFinder) Iterate(folders []string, hash []byte, iterFn func(string, string, int32) bool) bool {
|
func (f *BlockFinder) Iterate(folders []string, hash []byte, iterFn func(string, string, int32) bool) bool {
|
||||||
var key []byte
|
var key []byte
|
||||||
for _, folder := range folders {
|
for _, folder := range folders {
|
||||||
folderID := f.db.folderIdx.ID([]byte(folder))
|
key = blockKeyInto(key, hash, folder, "")
|
||||||
key = blockKeyInto(key, hash, folderID, "")
|
|
||||||
iter := f.db.NewIterator(util.BytesPrefix(key), nil)
|
iter := f.db.NewIterator(util.BytesPrefix(key), nil)
|
||||||
defer iter.Release()
|
defer iter.Release()
|
||||||
|
|
||||||
for iter.Next() && iter.Error() == nil {
|
for iter.Next() && iter.Error() == nil {
|
||||||
file := blockKeyName(iter.Key())
|
folder, file := fromBlockKey(iter.Key())
|
||||||
index := int32(binary.BigEndian.Uint32(iter.Value()))
|
index := int32(binary.BigEndian.Uint32(iter.Value()))
|
||||||
if iterFn(folder, osutil.NativeFilename(file), index) {
|
if iterFn(folder, osutil.NativeFilename(file), index) {
|
||||||
return true
|
return true
|
||||||
@@ -188,41 +194,48 @@ func (f *BlockFinder) Fix(folder, file string, index int32, oldHash, newHash []b
|
|||||||
buf := make([]byte, 4)
|
buf := make([]byte, 4)
|
||||||
binary.BigEndian.PutUint32(buf, uint32(index))
|
binary.BigEndian.PutUint32(buf, uint32(index))
|
||||||
|
|
||||||
folderID := f.db.folderIdx.ID([]byte(folder))
|
|
||||||
batch := new(leveldb.Batch)
|
batch := new(leveldb.Batch)
|
||||||
batch.Delete(blockKeyInto(nil, oldHash, folderID, file))
|
batch.Delete(blockKeyInto(nil, oldHash, folder, file))
|
||||||
batch.Put(blockKeyInto(nil, newHash, folderID, file), buf)
|
batch.Put(blockKeyInto(nil, newHash, folder, file), buf)
|
||||||
return f.db.Write(batch, nil)
|
return f.db.Write(batch, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// m.blockKey returns a byte slice encoding the following information:
|
// m.blockKey returns a byte slice encoding the following information:
|
||||||
// keyTypeBlock (1 byte)
|
// keyTypeBlock (1 byte)
|
||||||
// folder (4 bytes)
|
// folder (64 bytes)
|
||||||
// block hash (32 bytes)
|
// block hash (32 bytes)
|
||||||
// file name (variable size)
|
// file name (variable size)
|
||||||
func blockKeyInto(o, hash []byte, folder uint32, file string) []byte {
|
func blockKeyInto(o, hash []byte, folder, file string) []byte {
|
||||||
reqLen := keyPrefixLen + keyFolderLen + keyHashLen + len(file)
|
reqLen := 1 + 64 + 32 + len(file)
|
||||||
if cap(o) < reqLen {
|
if cap(o) < reqLen {
|
||||||
o = make([]byte, reqLen)
|
o = make([]byte, reqLen)
|
||||||
} else {
|
} else {
|
||||||
o = o[:reqLen]
|
o = o[:reqLen]
|
||||||
}
|
}
|
||||||
o[0] = KeyTypeBlock
|
o[0] = KeyTypeBlock
|
||||||
binary.BigEndian.PutUint32(o[keyPrefixLen:], folder)
|
copy(o[1:], []byte(folder))
|
||||||
copy(o[keyPrefixLen+keyFolderLen:], []byte(hash))
|
for i := len(folder); i < 64; i++ {
|
||||||
copy(o[keyPrefixLen+keyFolderLen+keyHashLen:], []byte(file))
|
o[1+i] = 0
|
||||||
|
}
|
||||||
|
copy(o[1+64:], []byte(hash))
|
||||||
|
copy(o[1+64+32:], []byte(file))
|
||||||
return o
|
return o
|
||||||
}
|
}
|
||||||
|
|
||||||
// blockKeyName returns the file name from the block key
|
func fromBlockKey(data []byte) (string, string) {
|
||||||
func blockKeyName(data []byte) string {
|
if len(data) < 1+64+32+1 {
|
||||||
if len(data) < keyPrefixLen+keyFolderLen+keyHashLen+1 {
|
|
||||||
panic("Incorrect key length")
|
panic("Incorrect key length")
|
||||||
}
|
}
|
||||||
if data[0] != KeyTypeBlock {
|
if data[0] != KeyTypeBlock {
|
||||||
panic("Incorrect key type")
|
panic("Incorrect key type")
|
||||||
}
|
}
|
||||||
|
|
||||||
file := string(data[keyPrefixLen+keyFolderLen+keyHashLen:])
|
file := string(data[1+64+32:])
|
||||||
return file
|
|
||||||
|
slice := data[1 : 1+64]
|
||||||
|
izero := bytes.IndexByte(slice, 0)
|
||||||
|
if izero > -1 {
|
||||||
|
return string(slice[:izero]), file
|
||||||
|
}
|
||||||
|
return string(slice), file
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
"github.com/syndtr/goleveldb/leveldb/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func genBlocks(n int) []protocol.BlockInfo {
|
func genBlocks(n int) []protocol.BlockInfo {
|
||||||
@@ -56,7 +55,7 @@ func setup() (*Instance, *BlockFinder) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func dbEmpty(db *Instance) bool {
|
func dbEmpty(db *Instance) bool {
|
||||||
iter := db.NewIterator(util.BytesPrefix([]byte{KeyTypeBlock}), nil)
|
iter := db.NewIterator(nil, nil)
|
||||||
defer iter.Release()
|
defer iter.Release()
|
||||||
if iter.Next() {
|
if iter.Next() {
|
||||||
return false
|
return false
|
||||||
@@ -71,7 +70,7 @@ func TestBlockMapAddUpdateWipe(t *testing.T) {
|
|||||||
t.Fatal("db not empty")
|
t.Fatal("db not empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
m := NewBlockMap(db, db.folderIdx.ID([]byte("folder1")))
|
m := NewBlockMap(db, "folder1")
|
||||||
|
|
||||||
f3.Flags |= protocol.FlagDirectory
|
f3.Flags |= protocol.FlagDirectory
|
||||||
|
|
||||||
@@ -153,8 +152,8 @@ func TestBlockMapAddUpdateWipe(t *testing.T) {
|
|||||||
func TestBlockFinderLookup(t *testing.T) {
|
func TestBlockFinderLookup(t *testing.T) {
|
||||||
db, f := setup()
|
db, f := setup()
|
||||||
|
|
||||||
m1 := NewBlockMap(db, db.folderIdx.ID([]byte("folder1")))
|
m1 := NewBlockMap(db, "folder1")
|
||||||
m2 := NewBlockMap(db, db.folderIdx.ID([]byte("folder2")))
|
m2 := NewBlockMap(db, "folder2")
|
||||||
|
|
||||||
err := m1.Add([]protocol.FileInfo{f1})
|
err := m1.Add([]protocol.FileInfo{f1})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -222,7 +221,7 @@ func TestBlockFinderFix(t *testing.T) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
m := NewBlockMap(db, db.folderIdx.ID([]byte("folder1")))
|
m := NewBlockMap(db, "folder1")
|
||||||
err := m.Add([]protocol.FileInfo{f1})
|
err := m.Add([]protocol.FileInfo{f1})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|||||||
@@ -42,8 +42,6 @@ const (
|
|||||||
KeyTypeDeviceStatistic
|
KeyTypeDeviceStatistic
|
||||||
KeyTypeFolderStatistic
|
KeyTypeFolderStatistic
|
||||||
KeyTypeVirtualMtime
|
KeyTypeVirtualMtime
|
||||||
KeyTypeFolderIdx
|
|
||||||
KeyTypeDeviceIdx
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type fileVersion struct {
|
type fileVersion struct {
|
||||||
|
|||||||
@@ -1,114 +0,0 @@
|
|||||||
// Copyright (C) 2015 The Syncthing Authors.
|
|
||||||
//
|
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
||||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
package db
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
|
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
|
||||||
)
|
|
||||||
|
|
||||||
// convertKeyFormat converts from the v0.12 to the v0.13 database format, to
|
|
||||||
// avoid having to do rescan. The change is in the key format for folder
|
|
||||||
// labels, so we basically just iterate over the database rewriting keys as
|
|
||||||
// necessary.
|
|
||||||
func convertKeyFormat(from, to *leveldb.DB) error {
|
|
||||||
l.Infoln("Converting database key format")
|
|
||||||
blocks, files, globals, unchanged := 0, 0, 0, 0
|
|
||||||
|
|
||||||
dbi := newDBInstance(to)
|
|
||||||
i := from.NewIterator(nil, nil)
|
|
||||||
for i.Next() {
|
|
||||||
key := i.Key()
|
|
||||||
switch key[0] {
|
|
||||||
case KeyTypeBlock:
|
|
||||||
folder, file := oldFromBlockKey(key)
|
|
||||||
folderIdx := dbi.folderIdx.ID([]byte(folder))
|
|
||||||
hash := key[1+64:]
|
|
||||||
newKey := blockKeyInto(nil, hash, folderIdx, file)
|
|
||||||
if err := to.Put(newKey, i.Value(), nil); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
blocks++
|
|
||||||
|
|
||||||
case KeyTypeDevice:
|
|
||||||
newKey := dbi.deviceKey(oldDeviceKeyFolder(key), oldDeviceKeyDevice(key), oldDeviceKeyName(key))
|
|
||||||
if err := to.Put(newKey, i.Value(), nil); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
files++
|
|
||||||
|
|
||||||
case KeyTypeGlobal:
|
|
||||||
newKey := dbi.globalKey(oldGlobalKeyFolder(key), oldGlobalKeyName(key))
|
|
||||||
if err := to.Put(newKey, i.Value(), nil); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
globals++
|
|
||||||
|
|
||||||
case KeyTypeVirtualMtime:
|
|
||||||
// Cannot be converted, we drop it instead :(
|
|
||||||
|
|
||||||
default:
|
|
||||||
if err := to.Put(key, i.Value(), nil); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
unchanged++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
l.Infof("Converted %d blocks, %d files, %d globals (%d unchanged).", blocks, files, globals, unchanged)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func oldDeviceKeyFolder(key []byte) []byte {
|
|
||||||
folder := key[1 : 1+64]
|
|
||||||
izero := bytes.IndexByte(folder, 0)
|
|
||||||
if izero < 0 {
|
|
||||||
return folder
|
|
||||||
}
|
|
||||||
return folder[:izero]
|
|
||||||
}
|
|
||||||
|
|
||||||
func oldDeviceKeyDevice(key []byte) []byte {
|
|
||||||
return key[1+64 : 1+64+32]
|
|
||||||
}
|
|
||||||
|
|
||||||
func oldDeviceKeyName(key []byte) []byte {
|
|
||||||
return key[1+64+32:]
|
|
||||||
}
|
|
||||||
|
|
||||||
func oldGlobalKeyName(key []byte) []byte {
|
|
||||||
return key[1+64:]
|
|
||||||
}
|
|
||||||
|
|
||||||
func oldGlobalKeyFolder(key []byte) []byte {
|
|
||||||
folder := key[1 : 1+64]
|
|
||||||
izero := bytes.IndexByte(folder, 0)
|
|
||||||
if izero < 0 {
|
|
||||||
return folder
|
|
||||||
}
|
|
||||||
return folder[:izero]
|
|
||||||
}
|
|
||||||
|
|
||||||
func oldFromBlockKey(data []byte) (string, string) {
|
|
||||||
if len(data) < 1+64+32+1 {
|
|
||||||
panic("Incorrect key length")
|
|
||||||
}
|
|
||||||
if data[0] != KeyTypeBlock {
|
|
||||||
panic("Incorrect key type")
|
|
||||||
}
|
|
||||||
|
|
||||||
file := string(data[1+64+32:])
|
|
||||||
|
|
||||||
slice := data[1 : 1+64]
|
|
||||||
izero := bytes.IndexByte(slice, 0)
|
|
||||||
if izero > -1 {
|
|
||||||
return string(slice[:izero]), file
|
|
||||||
}
|
|
||||||
return string(slice), file
|
|
||||||
}
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
// Copyright (C) 2015 The Syncthing Authors.
|
|
||||||
//
|
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
||||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
package db
|
|
||||||
|
|
||||||
import (
|
|
||||||
"archive/zip"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestLabelConversion(t *testing.T) {
|
|
||||||
os.RemoveAll("testdata/oldformat.db")
|
|
||||||
defer os.RemoveAll("testdata/oldformat.db")
|
|
||||||
os.RemoveAll("testdata/newformat.db")
|
|
||||||
defer os.RemoveAll("testdata/newformat.db")
|
|
||||||
|
|
||||||
if err := unzip("testdata/oldformat.db.zip", "testdata"); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
odb, err := leveldb.OpenFile("testdata/oldformat.db", nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ldb, err := leveldb.OpenFile("testdata/newformat.db", nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = convertKeyFormat(odb, ldb); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
ldb.Close()
|
|
||||||
odb.Close()
|
|
||||||
|
|
||||||
inst, err := Open("testdata/newformat.db")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fs := NewFileSet("default", inst)
|
|
||||||
files, deleted, _ := fs.GlobalSize()
|
|
||||||
if files+deleted != 953 {
|
|
||||||
// Expected number of global entries determined by
|
|
||||||
// ../../bin/stindex testdata/oldformat.db/ | grep global | grep -c default
|
|
||||||
t.Errorf("Conversion error, global list differs (%d != 953)", files+deleted)
|
|
||||||
}
|
|
||||||
|
|
||||||
files, deleted, _ = fs.LocalSize()
|
|
||||||
if files+deleted != 953 {
|
|
||||||
t.Errorf("Conversion error, device list differs (%d != 953)", files+deleted)
|
|
||||||
}
|
|
||||||
|
|
||||||
f := NewBlockFinder(inst)
|
|
||||||
// [block] F:"default" H:1c25dea9003cc16216e2a22900be1ec1cc5aaf270442904e2f9812c314e929d8 N:"f/f2/f25f1b3e6e029231b933531b2138796d" I:3
|
|
||||||
h := []byte{0x1c, 0x25, 0xde, 0xa9, 0x00, 0x3c, 0xc1, 0x62, 0x16, 0xe2, 0xa2, 0x29, 0x00, 0xbe, 0x1e, 0xc1, 0xcc, 0x5a, 0xaf, 0x27, 0x04, 0x42, 0x90, 0x4e, 0x2f, 0x98, 0x12, 0xc3, 0x14, 0xe9, 0x29, 0xd8}
|
|
||||||
found := 0
|
|
||||||
f.Iterate([]string{"default"}, h, func(folder, file string, idx int32) bool {
|
|
||||||
if folder == "default" && file == filepath.FromSlash("f/f2/f25f1b3e6e029231b933531b2138796d") && idx == 3 {
|
|
||||||
found++
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
if found != 1 {
|
|
||||||
t.Errorf("Found %d blocks instead of expected 1", found)
|
|
||||||
}
|
|
||||||
|
|
||||||
inst.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func unzip(src, dest string) error {
|
|
||||||
r, err := zip.OpenReader(src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err := r.Close(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
os.MkdirAll(dest, 0755)
|
|
||||||
|
|
||||||
// Closure to address file descriptors issue with all the deferred .Close() methods
|
|
||||||
extractAndWriteFile := func(f *zip.File) error {
|
|
||||||
rc, err := f.Open()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err := rc.Close(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
path := filepath.Join(dest, f.Name)
|
|
||||||
|
|
||||||
if f.FileInfo().IsDir() {
|
|
||||||
os.MkdirAll(path, f.Mode())
|
|
||||||
} else {
|
|
||||||
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err := f.Close(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
_, err = io.Copy(f, rc)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, f := range r.File {
|
|
||||||
err := extractAndWriteFile(f)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
+50
-206
@@ -8,15 +8,11 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/syncthing/syncthing/lib/osutil"
|
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
"github.com/syndtr/goleveldb/leveldb/errors"
|
"github.com/syndtr/goleveldb/leveldb/errors"
|
||||||
"github.com/syndtr/goleveldb/leveldb/iterator"
|
"github.com/syndtr/goleveldb/leveldb/iterator"
|
||||||
@@ -29,33 +25,14 @@ type deletionHandler func(t readWriteTransaction, folder, device, name []byte, d
|
|||||||
|
|
||||||
type Instance struct {
|
type Instance struct {
|
||||||
*leveldb.DB
|
*leveldb.DB
|
||||||
folderIdx *smallIndex
|
|
||||||
deviceIdx *smallIndex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
|
||||||
keyPrefixLen = 1
|
|
||||||
keyFolderLen = 4 // indexed
|
|
||||||
keyDeviceLen = 4 // indexed
|
|
||||||
keyHashLen = 32
|
|
||||||
)
|
|
||||||
|
|
||||||
func Open(file string) (*Instance, error) {
|
func Open(file string) (*Instance, error) {
|
||||||
opts := &opt.Options{
|
opts := &opt.Options{
|
||||||
OpenFilesCacheCapacity: 100,
|
OpenFilesCacheCapacity: 100,
|
||||||
WriteBuffer: 4 << 20,
|
WriteBuffer: 4 << 20,
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := os.Stat(file); os.IsNotExist(err) {
|
|
||||||
// The file we are looking to open does not exist. This may be the
|
|
||||||
// first launch so we should look for an old version and try to
|
|
||||||
// convert it.
|
|
||||||
if err := checkConvertDatabase(file); err != nil {
|
|
||||||
l.Infoln("Converting old database:", err)
|
|
||||||
l.Infoln("Will rescan from scratch.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
db, err := leveldb.OpenFile(file, opts)
|
db, err := leveldb.OpenFile(file, opts)
|
||||||
if leveldbIsCorrupted(err) {
|
if leveldbIsCorrupted(err) {
|
||||||
db, err = leveldb.RecoverFile(file, opts)
|
db, err = leveldb.RecoverFile(file, opts)
|
||||||
@@ -83,12 +60,9 @@ func OpenMemory() *Instance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newDBInstance(db *leveldb.DB) *Instance {
|
func newDBInstance(db *leveldb.DB) *Instance {
|
||||||
i := &Instance{
|
return &Instance{
|
||||||
DB: db,
|
DB: db,
|
||||||
}
|
}
|
||||||
i.folderIdx = newSmallIndex(i, []byte{KeyTypeFolderIdx})
|
|
||||||
i.deviceIdx = newSmallIndex(i, []byte{KeyTypeDeviceIdx})
|
|
||||||
return i
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Instance) Compact() error {
|
func (db *Instance) Compact() error {
|
||||||
@@ -98,10 +72,13 @@ func (db *Instance) Compact() error {
|
|||||||
func (db *Instance) genericReplace(folder, device []byte, fs []protocol.FileInfo, localSize, globalSize *sizeTracker, deleteFn deletionHandler) int64 {
|
func (db *Instance) genericReplace(folder, device []byte, fs []protocol.FileInfo, localSize, globalSize *sizeTracker, deleteFn deletionHandler) int64 {
|
||||||
sort.Sort(fileList(fs)) // sort list on name, same as in the database
|
sort.Sort(fileList(fs)) // sort list on name, same as in the database
|
||||||
|
|
||||||
|
start := db.deviceKey(folder, device, nil) // before all folder/device files
|
||||||
|
limit := db.deviceKey(folder, device, []byte{0xff, 0xff, 0xff, 0xff}) // after all folder/device files
|
||||||
|
|
||||||
t := db.newReadWriteTransaction()
|
t := db.newReadWriteTransaction()
|
||||||
defer t.close()
|
defer t.close()
|
||||||
|
|
||||||
dbi := t.NewIterator(util.BytesPrefix(db.deviceKey(folder, device, nil)[:keyPrefixLen+keyFolderLen+keyDeviceLen]), nil)
|
dbi := t.NewIterator(&util.Range{Start: start, Limit: limit}, nil)
|
||||||
defer dbi.Release()
|
defer dbi.Release()
|
||||||
|
|
||||||
moreDb := dbi.Next()
|
moreDb := dbi.Next()
|
||||||
@@ -259,19 +236,15 @@ func (db *Instance) updateFiles(folder, device []byte, fs []protocol.FileInfo, l
|
|||||||
return maxLocalVer
|
return maxLocalVer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Instance) withHave(folder, device []byte, truncate bool, fn Iterator) {
|
func (db *Instance) withHave(folder, device, prefix []byte, truncate bool, fn Iterator) {
|
||||||
t := db.newReadOnlyTransaction()
|
t := db.newReadOnlyTransaction()
|
||||||
defer t.close()
|
defer t.close()
|
||||||
|
|
||||||
dbi := t.NewIterator(util.BytesPrefix(db.deviceKey(folder, device, nil)[:keyPrefixLen+keyFolderLen+keyDeviceLen]), nil)
|
dbi := t.NewIterator(util.BytesPrefix(db.deviceKey(folder, device, prefix)[:1+64+32+len(prefix)]), nil)
|
||||||
defer dbi.Release()
|
defer dbi.Release()
|
||||||
|
|
||||||
for dbi.Next() {
|
for dbi.Next() {
|
||||||
// The iterator function may keep a reference to the unmarshalled
|
f, err := unmarshalTrunc(dbi.Value(), truncate)
|
||||||
// struct, which in turn references the buffer it was unmarshalled
|
|
||||||
// from. dbi.Value() just returns an internal slice that it reuses, so
|
|
||||||
// we need to copy it.
|
|
||||||
f, err := unmarshalTrunc(append([]byte{}, dbi.Value()...), truncate)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -282,20 +255,19 @@ func (db *Instance) withHave(folder, device []byte, truncate bool, fn Iterator)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (db *Instance) withAllFolderTruncated(folder []byte, fn func(device []byte, f FileInfoTruncated) bool) {
|
func (db *Instance) withAllFolderTruncated(folder []byte, fn func(device []byte, f FileInfoTruncated) bool) {
|
||||||
|
start := db.deviceKey(folder, nil, nil) // before all folder/device files
|
||||||
|
limit := db.deviceKey(folder, protocol.LocalDeviceID[:], []byte{0xff, 0xff, 0xff, 0xff}) // after all folder/device files
|
||||||
|
|
||||||
t := db.newReadWriteTransaction()
|
t := db.newReadWriteTransaction()
|
||||||
defer t.close()
|
defer t.close()
|
||||||
|
|
||||||
dbi := t.NewIterator(util.BytesPrefix(db.deviceKey(folder, nil, nil)[:keyPrefixLen+keyFolderLen]), nil)
|
dbi := t.NewIterator(&util.Range{Start: start, Limit: limit}, nil)
|
||||||
defer dbi.Release()
|
defer dbi.Release()
|
||||||
|
|
||||||
for dbi.Next() {
|
for dbi.Next() {
|
||||||
device := db.deviceKeyDevice(dbi.Key())
|
device := db.deviceKeyDevice(dbi.Key())
|
||||||
var f FileInfoTruncated
|
var f FileInfoTruncated
|
||||||
// The iterator function may keep a reference to the unmarshalled
|
err := f.UnmarshalXDR(dbi.Value())
|
||||||
// struct, which in turn references the buffer it was unmarshalled
|
|
||||||
// from. dbi.Value() just returns an internal slice that it reuses, so
|
|
||||||
// we need to copy it.
|
|
||||||
err := f.UnmarshalXDR(append([]byte{}, dbi.Value()...))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -384,10 +356,7 @@ func (db *Instance) withGlobal(folder, prefix []byte, truncate bool, fn Iterator
|
|||||||
l.Debugf("vl.versions[0].device: %x", vl.versions[0].device)
|
l.Debugf("vl.versions[0].device: %x", vl.versions[0].device)
|
||||||
l.Debugf("name: %q (%x)", name, name)
|
l.Debugf("name: %q (%x)", name, name)
|
||||||
l.Debugf("fk: %q", fk)
|
l.Debugf("fk: %q", fk)
|
||||||
l.Debugf("fk: %x %x %x",
|
l.Debugf("fk: %x %x %x", fk[1:1+64], fk[1+64:1+64+32], fk[1+64+32:])
|
||||||
fk[keyPrefixLen:keyPrefixLen+keyFolderLen],
|
|
||||||
fk[keyPrefixLen+keyFolderLen:keyPrefixLen+keyFolderLen+keyDeviceLen],
|
|
||||||
fk[keyPrefixLen+keyFolderLen+keyDeviceLen:])
|
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,10 +400,13 @@ func (db *Instance) availability(folder, file []byte) []protocol.DeviceID {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (db *Instance) withNeed(folder, device []byte, truncate bool, fn Iterator) {
|
func (db *Instance) withNeed(folder, device []byte, truncate bool, fn Iterator) {
|
||||||
|
start := db.globalKey(folder, nil)
|
||||||
|
limit := db.globalKey(folder, []byte{0xff, 0xff, 0xff, 0xff})
|
||||||
|
|
||||||
t := db.newReadOnlyTransaction()
|
t := db.newReadOnlyTransaction()
|
||||||
defer t.close()
|
defer t.close()
|
||||||
|
|
||||||
dbi := t.NewIterator(util.BytesPrefix(db.globalKey(folder, nil)[:keyPrefixLen+keyFolderLen]), nil)
|
dbi := t.NewIterator(&util.Range{Start: start, Limit: limit}, nil)
|
||||||
defer dbi.Release()
|
defer dbi.Release()
|
||||||
|
|
||||||
var fk []byte
|
var fk []byte
|
||||||
@@ -571,7 +543,9 @@ func (db *Instance) checkGlobals(folder []byte, globalSize *sizeTracker) {
|
|||||||
t := db.newReadWriteTransaction()
|
t := db.newReadWriteTransaction()
|
||||||
defer t.close()
|
defer t.close()
|
||||||
|
|
||||||
dbi := t.NewIterator(util.BytesPrefix(db.globalKey(folder, nil)[:keyPrefixLen+keyFolderLen]), nil)
|
start := db.globalKey(folder, nil)
|
||||||
|
limit := db.globalKey(folder, []byte{0xff, 0xff, 0xff, 0xff})
|
||||||
|
dbi := t.NewIterator(&util.Range{Start: start, Limit: limit}, nil)
|
||||||
defer dbi.Release()
|
defer dbi.Release()
|
||||||
|
|
||||||
var fk []byte
|
var fk []byte
|
||||||
@@ -621,72 +595,71 @@ func (db *Instance) checkGlobals(folder []byte, globalSize *sizeTracker) {
|
|||||||
|
|
||||||
// deviceKey returns a byte slice encoding the following information:
|
// deviceKey returns a byte slice encoding the following information:
|
||||||
// keyTypeDevice (1 byte)
|
// keyTypeDevice (1 byte)
|
||||||
// folder (4 bytes)
|
// folder (64 bytes)
|
||||||
// device (4 bytes)
|
// device (32 bytes)
|
||||||
// name (variable size)
|
// name (variable size)
|
||||||
func (db *Instance) deviceKey(folder, device, file []byte) []byte {
|
func (db *Instance) deviceKey(folder, device, file []byte) []byte {
|
||||||
return db.deviceKeyInto(nil, folder, device, file)
|
return db.deviceKeyInto(nil, folder, device, file)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Instance) deviceKeyInto(k []byte, folder, device, file []byte) []byte {
|
func (db *Instance) deviceKeyInto(k []byte, folder, device, file []byte) []byte {
|
||||||
reqLen := keyPrefixLen + keyFolderLen + keyDeviceLen + len(file)
|
reqLen := 1 + 64 + 32 + len(file)
|
||||||
if len(k) < reqLen {
|
if len(k) < reqLen {
|
||||||
k = make([]byte, reqLen)
|
k = make([]byte, reqLen)
|
||||||
}
|
}
|
||||||
k[0] = KeyTypeDevice
|
k[0] = KeyTypeDevice
|
||||||
binary.BigEndian.PutUint32(k[keyPrefixLen:], db.folderIdx.ID(folder))
|
if len(folder) > 64 {
|
||||||
binary.BigEndian.PutUint32(k[keyPrefixLen+keyFolderLen:], db.deviceIdx.ID(device))
|
panic("folder name too long")
|
||||||
copy(k[keyPrefixLen+keyFolderLen+keyDeviceLen:], []byte(file))
|
}
|
||||||
|
copy(k[1:], []byte(folder))
|
||||||
|
copy(k[1+64:], device[:])
|
||||||
|
copy(k[1+64+32:], []byte(file))
|
||||||
return k[:reqLen]
|
return k[:reqLen]
|
||||||
}
|
}
|
||||||
|
|
||||||
// deviceKeyName returns the device ID from the key
|
|
||||||
func (db *Instance) deviceKeyName(key []byte) []byte {
|
func (db *Instance) deviceKeyName(key []byte) []byte {
|
||||||
return key[keyPrefixLen+keyFolderLen+keyDeviceLen:]
|
return key[1+64+32:]
|
||||||
}
|
}
|
||||||
|
|
||||||
// deviceKeyFolder returns the folder name from the key
|
|
||||||
func (db *Instance) deviceKeyFolder(key []byte) []byte {
|
func (db *Instance) deviceKeyFolder(key []byte) []byte {
|
||||||
folder, ok := db.folderIdx.Val(binary.BigEndian.Uint32(key[keyPrefixLen:]))
|
folder := key[1 : 1+64]
|
||||||
if !ok {
|
izero := bytes.IndexByte(folder, 0)
|
||||||
panic("bug: lookup of nonexistent folder ID")
|
if izero < 0 {
|
||||||
|
return folder
|
||||||
}
|
}
|
||||||
return folder
|
return folder[:izero]
|
||||||
}
|
}
|
||||||
|
|
||||||
// deviceKeyDevice returns the device ID from the key
|
|
||||||
func (db *Instance) deviceKeyDevice(key []byte) []byte {
|
func (db *Instance) deviceKeyDevice(key []byte) []byte {
|
||||||
device, ok := db.deviceIdx.Val(binary.BigEndian.Uint32(key[keyPrefixLen+keyFolderLen:]))
|
return key[1+64 : 1+64+32]
|
||||||
if !ok {
|
|
||||||
panic("bug: lookup of nonexistent device ID")
|
|
||||||
}
|
|
||||||
return device
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// globalKey returns a byte slice encoding the following information:
|
// globalKey returns a byte slice encoding the following information:
|
||||||
// keyTypeGlobal (1 byte)
|
// keyTypeGlobal (1 byte)
|
||||||
// folder (4 bytes)
|
// folder (64 bytes)
|
||||||
// name (variable size)
|
// name (variable size)
|
||||||
func (db *Instance) globalKey(folder, file []byte) []byte {
|
func (db *Instance) globalKey(folder, file []byte) []byte {
|
||||||
k := make([]byte, keyPrefixLen+keyFolderLen+len(file))
|
k := make([]byte, 1+64+len(file))
|
||||||
k[0] = KeyTypeGlobal
|
k[0] = KeyTypeGlobal
|
||||||
binary.BigEndian.PutUint32(k[keyPrefixLen:], db.folderIdx.ID(folder))
|
if len(folder) > 64 {
|
||||||
copy(k[keyPrefixLen+keyFolderLen:], []byte(file))
|
panic("folder name too long")
|
||||||
|
}
|
||||||
|
copy(k[1:], []byte(folder))
|
||||||
|
copy(k[1+64:], []byte(file))
|
||||||
return k
|
return k
|
||||||
}
|
}
|
||||||
|
|
||||||
// globalKeyName returns the filename from the key
|
|
||||||
func (db *Instance) globalKeyName(key []byte) []byte {
|
func (db *Instance) globalKeyName(key []byte) []byte {
|
||||||
return key[keyPrefixLen+keyFolderLen:]
|
return key[1+64:]
|
||||||
}
|
}
|
||||||
|
|
||||||
// globalKeyFolder returns the folder name from the key
|
|
||||||
func (db *Instance) globalKeyFolder(key []byte) []byte {
|
func (db *Instance) globalKeyFolder(key []byte) []byte {
|
||||||
folder, ok := db.folderIdx.Val(binary.BigEndian.Uint32(key[keyPrefixLen:]))
|
folder := key[1 : 1+64]
|
||||||
if !ok {
|
izero := bytes.IndexByte(folder, 0)
|
||||||
panic("bug: lookup of nonexistent folder ID")
|
if izero < 0 {
|
||||||
|
return folder
|
||||||
}
|
}
|
||||||
return folder
|
return folder[:izero]
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmarshalTrunc(bs []byte, truncate bool) (FileIntf, error) {
|
func unmarshalTrunc(bs []byte, truncate bool) (FileIntf, error) {
|
||||||
@@ -716,132 +689,3 @@ func leveldbIsCorrupted(err error) bool {
|
|||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkConvertDatabase tries to convert an existing old (v0.11) database to
|
|
||||||
// new (v0.13) format.
|
|
||||||
func checkConvertDatabase(dbFile string) error {
|
|
||||||
oldLoc := filepath.Join(filepath.Dir(dbFile), "index-v0.11.0.db")
|
|
||||||
if _, err := os.Stat(oldLoc); os.IsNotExist(err) {
|
|
||||||
// The old database file does not exist; that's ok, continue as if
|
|
||||||
// everything succeeded.
|
|
||||||
return nil
|
|
||||||
} else if err != nil {
|
|
||||||
// Any other error is weird.
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// There exists a database in the old format. We run a one time
|
|
||||||
// conversion from old to new.
|
|
||||||
|
|
||||||
fromDb, err := leveldb.OpenFile(oldLoc, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
toDb, err := leveldb.OpenFile(dbFile, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = convertKeyFormat(fromDb, toDb)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = toDb.Close()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// We've done this one, we don't want to do it again (if the user runs
|
|
||||||
// -reset or so). We don't care too much about errors any more at this stage.
|
|
||||||
fromDb.Close()
|
|
||||||
osutil.Rename(oldLoc, oldLoc+".converted")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// A smallIndex is an in memory bidirectional []byte to uint32 map. It gives
|
|
||||||
// fast lookups in both directions and persists to the database. Don't use for
|
|
||||||
// storing more items than fit comfortably in RAM.
|
|
||||||
type smallIndex struct {
|
|
||||||
db *Instance
|
|
||||||
prefix []byte
|
|
||||||
id2val map[uint32]string
|
|
||||||
val2id map[string]uint32
|
|
||||||
nextID uint32
|
|
||||||
mut sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSmallIndex(db *Instance, prefix []byte) *smallIndex {
|
|
||||||
idx := &smallIndex{
|
|
||||||
db: db,
|
|
||||||
prefix: prefix,
|
|
||||||
id2val: make(map[uint32]string),
|
|
||||||
val2id: make(map[string]uint32),
|
|
||||||
mut: sync.NewMutex(),
|
|
||||||
}
|
|
||||||
idx.load()
|
|
||||||
return idx
|
|
||||||
}
|
|
||||||
|
|
||||||
// load iterates over the prefix space in the database and populates the in
|
|
||||||
// memory maps.
|
|
||||||
func (i *smallIndex) load() {
|
|
||||||
tr := i.db.newReadOnlyTransaction()
|
|
||||||
it := tr.NewIterator(util.BytesPrefix(i.prefix), nil)
|
|
||||||
for it.Next() {
|
|
||||||
val := string(it.Value())
|
|
||||||
id := binary.BigEndian.Uint32(it.Key()[len(i.prefix):])
|
|
||||||
i.id2val[id] = val
|
|
||||||
i.val2id[val] = id
|
|
||||||
if id >= i.nextID {
|
|
||||||
i.nextID = id + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
it.Release()
|
|
||||||
tr.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID returns the index number for the given byte slice, allocating a new one
|
|
||||||
// and persisting this to the database if necessary.
|
|
||||||
func (i *smallIndex) ID(val []byte) uint32 {
|
|
||||||
i.mut.Lock()
|
|
||||||
// intentionally avoiding defer here as we want this call to be as fast as
|
|
||||||
// possible in the general case (folder ID already exists). The map lookup
|
|
||||||
// with the conversion of []byte to string is compiler optimized to not
|
|
||||||
// copy the []byte, which is why we don't assign it to a temp variable
|
|
||||||
// here.
|
|
||||||
if id, ok := i.val2id[string(val)]; ok {
|
|
||||||
i.mut.Unlock()
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
|
|
||||||
id := i.nextID
|
|
||||||
i.nextID++
|
|
||||||
|
|
||||||
valStr := string(val)
|
|
||||||
i.val2id[valStr] = id
|
|
||||||
i.id2val[id] = valStr
|
|
||||||
|
|
||||||
key := make([]byte, len(i.prefix)+8) // prefix plus uint32 id
|
|
||||||
copy(key, i.prefix)
|
|
||||||
binary.BigEndian.PutUint32(key[len(i.prefix):], id)
|
|
||||||
i.db.Put(key, val, nil)
|
|
||||||
|
|
||||||
i.mut.Unlock()
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
|
|
||||||
// Val returns the value for the given index number, or (nil, false) if there
|
|
||||||
// is no such index number.
|
|
||||||
func (i *smallIndex) Val(id uint32) ([]byte, bool) {
|
|
||||||
i.mut.Lock()
|
|
||||||
val, ok := i.id2val[id]
|
|
||||||
i.mut.Unlock()
|
|
||||||
if !ok {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
return []byte(val), true
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -16,9 +16,7 @@ func TestDeviceKey(t *testing.T) {
|
|||||||
dev := []byte("device67890123456789012345678901")
|
dev := []byte("device67890123456789012345678901")
|
||||||
name := []byte("name")
|
name := []byte("name")
|
||||||
|
|
||||||
db := OpenMemory()
|
db := &Instance{}
|
||||||
db.folderIdx.ID(fld)
|
|
||||||
db.deviceIdx.ID(dev)
|
|
||||||
|
|
||||||
key := db.deviceKey(fld, dev, name)
|
key := db.deviceKey(fld, dev, name)
|
||||||
|
|
||||||
@@ -40,8 +38,7 @@ func TestGlobalKey(t *testing.T) {
|
|||||||
fld := []byte("folder6789012345678901234567890123456789012345678901234567890123")
|
fld := []byte("folder6789012345678901234567890123456789012345678901234567890123")
|
||||||
name := []byte("name")
|
name := []byte("name")
|
||||||
|
|
||||||
db := OpenMemory()
|
db := &Instance{}
|
||||||
db.folderIdx.ID(fld)
|
|
||||||
|
|
||||||
key := db.globalKey(fld, name)
|
key := db.globalKey(fld, name)
|
||||||
|
|
||||||
|
|||||||
+69
-44
@@ -5,6 +5,9 @@
|
|||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
|
||||||
"github.com/calmh/xdr"
|
"github.com/calmh/xdr"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,8 +22,10 @@ fileVersion Structure:
|
|||||||
\ Vector Structure \
|
\ Vector Structure \
|
||||||
/ /
|
/ /
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Length of device |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
/ /
|
/ /
|
||||||
\ device (length + padded data) \
|
\ device (variable length) \
|
||||||
/ /
|
/ /
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
@@ -32,15 +37,13 @@ struct fileVersion {
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func (o fileVersion) XDRSize() int {
|
func (o fileVersion) EncodeXDR(w io.Writer) (int, error) {
|
||||||
return o.version.XDRSize() +
|
var xw = xdr.NewWriter(w)
|
||||||
4 + len(o.device) + xdr.Padding(len(o.device))
|
return o.EncodeXDRInto(xw)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o fileVersion) MarshalXDR() ([]byte, error) {
|
func (o fileVersion) MarshalXDR() ([]byte, error) {
|
||||||
buf := make([]byte, o.XDRSize())
|
return o.AppendXDR(make([]byte, 0, 128))
|
||||||
m := &xdr.Marshaller{Data: buf}
|
|
||||||
return buf, o.MarshalXDRInto(m)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o fileVersion) MustMarshalXDR() []byte {
|
func (o fileVersion) MustMarshalXDR() []byte {
|
||||||
@@ -51,22 +54,37 @@ func (o fileVersion) MustMarshalXDR() []byte {
|
|||||||
return bs
|
return bs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o fileVersion) MarshalXDRInto(m *xdr.Marshaller) error {
|
func (o fileVersion) AppendXDR(bs []byte) ([]byte, error) {
|
||||||
if err := o.version.MarshalXDRInto(m); err != nil {
|
var aw = xdr.AppendWriter(bs)
|
||||||
return err
|
var xw = xdr.NewWriter(&aw)
|
||||||
|
_, err := o.EncodeXDRInto(xw)
|
||||||
|
return []byte(aw), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o fileVersion) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
|
_, err := o.version.EncodeXDRInto(xw)
|
||||||
|
if err != nil {
|
||||||
|
return xw.Tot(), err
|
||||||
}
|
}
|
||||||
m.MarshalBytes(o.device)
|
xw.WriteBytes(o.device)
|
||||||
return m.Error
|
return xw.Tot(), xw.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *fileVersion) DecodeXDR(r io.Reader) error {
|
||||||
|
xr := xdr.NewReader(r)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *fileVersion) UnmarshalXDR(bs []byte) error {
|
func (o *fileVersion) UnmarshalXDR(bs []byte) error {
|
||||||
u := &xdr.Unmarshaller{Data: bs}
|
var br = bytes.NewReader(bs)
|
||||||
return o.UnmarshalXDRFrom(u)
|
var xr = xdr.NewReader(br)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
}
|
}
|
||||||
func (o *fileVersion) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
|
|
||||||
(&o.version).UnmarshalXDRFrom(u)
|
func (o *fileVersion) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
o.device = u.UnmarshalBytes()
|
(&o.version).DecodeXDRFrom(xr)
|
||||||
return u.Error
|
o.device = xr.ReadBytes()
|
||||||
|
return xr.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -90,14 +108,13 @@ struct versionList {
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func (o versionList) XDRSize() int {
|
func (o versionList) EncodeXDR(w io.Writer) (int, error) {
|
||||||
return 4 + xdr.SizeOfSlice(o.versions)
|
var xw = xdr.NewWriter(w)
|
||||||
|
return o.EncodeXDRInto(xw)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o versionList) MarshalXDR() ([]byte, error) {
|
func (o versionList) MarshalXDR() ([]byte, error) {
|
||||||
buf := make([]byte, o.XDRSize())
|
return o.AppendXDR(make([]byte, 0, 128))
|
||||||
m := &xdr.Marshaller{Data: buf}
|
|
||||||
return buf, o.MarshalXDRInto(m)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o versionList) MustMarshalXDR() []byte {
|
func (o versionList) MustMarshalXDR() []byte {
|
||||||
@@ -108,35 +125,43 @@ func (o versionList) MustMarshalXDR() []byte {
|
|||||||
return bs
|
return bs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o versionList) MarshalXDRInto(m *xdr.Marshaller) error {
|
func (o versionList) AppendXDR(bs []byte) ([]byte, error) {
|
||||||
m.MarshalUint32(uint32(len(o.versions)))
|
var aw = xdr.AppendWriter(bs)
|
||||||
|
var xw = xdr.NewWriter(&aw)
|
||||||
|
_, err := o.EncodeXDRInto(xw)
|
||||||
|
return []byte(aw), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o versionList) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
|
xw.WriteUint32(uint32(len(o.versions)))
|
||||||
for i := range o.versions {
|
for i := range o.versions {
|
||||||
if err := o.versions[i].MarshalXDRInto(m); err != nil {
|
_, err := o.versions[i].EncodeXDRInto(xw)
|
||||||
return err
|
if err != nil {
|
||||||
|
return xw.Tot(), err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return m.Error
|
return xw.Tot(), xw.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *versionList) DecodeXDR(r io.Reader) error {
|
||||||
|
xr := xdr.NewReader(r)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *versionList) UnmarshalXDR(bs []byte) error {
|
func (o *versionList) UnmarshalXDR(bs []byte) error {
|
||||||
u := &xdr.Unmarshaller{Data: bs}
|
var br = bytes.NewReader(bs)
|
||||||
return o.UnmarshalXDRFrom(u)
|
var xr = xdr.NewReader(br)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
}
|
}
|
||||||
func (o *versionList) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
|
|
||||||
_versionsSize := int(u.UnmarshalUint32())
|
func (o *versionList) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
|
_versionsSize := int(xr.ReadUint32())
|
||||||
if _versionsSize < 0 {
|
if _versionsSize < 0 {
|
||||||
return xdr.ElementSizeExceeded("versions", _versionsSize, 0)
|
return xdr.ElementSizeExceeded("versions", _versionsSize, 0)
|
||||||
} else if _versionsSize == 0 {
|
|
||||||
o.versions = nil
|
|
||||||
} else {
|
|
||||||
if _versionsSize <= len(o.versions) {
|
|
||||||
o.versions = o.versions[:_versionsSize]
|
|
||||||
} else {
|
|
||||||
o.versions = make([]fileVersion, _versionsSize)
|
|
||||||
}
|
|
||||||
for i := range o.versions {
|
|
||||||
(&o.versions[i]).UnmarshalXDRFrom(u)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return u.Error
|
o.versions = make([]fileVersion, _versionsSize)
|
||||||
|
for i := range o.versions {
|
||||||
|
(&o.versions[i]).DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
return xr.Error()
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-4
@@ -97,7 +97,7 @@ func NewFileSet(folder string, db *Instance) *FileSet {
|
|||||||
localVersion: make(map[protocol.DeviceID]int64),
|
localVersion: make(map[protocol.DeviceID]int64),
|
||||||
folder: folder,
|
folder: folder,
|
||||||
db: db,
|
db: db,
|
||||||
blockmap: NewBlockMap(db, db.folderIdx.ID([]byte(folder))),
|
blockmap: NewBlockMap(db, folder),
|
||||||
mutex: sync.NewMutex(),
|
mutex: sync.NewMutex(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,14 +171,18 @@ func (s *FileSet) WithNeedTruncated(device protocol.DeviceID, fn Iterator) {
|
|||||||
|
|
||||||
func (s *FileSet) WithHave(device protocol.DeviceID, fn Iterator) {
|
func (s *FileSet) WithHave(device protocol.DeviceID, fn Iterator) {
|
||||||
l.Debugf("%s WithHave(%v)", s.folder, device)
|
l.Debugf("%s WithHave(%v)", s.folder, device)
|
||||||
s.db.withHave([]byte(s.folder), device[:], false, nativeFileIterator(fn))
|
s.db.withHave([]byte(s.folder), device[:], nil, false, nativeFileIterator(fn))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FileSet) WithHaveTruncated(device protocol.DeviceID, fn Iterator) {
|
func (s *FileSet) WithHaveTruncated(device protocol.DeviceID, fn Iterator) {
|
||||||
l.Debugf("%s WithHaveTruncated(%v)", s.folder, device)
|
l.Debugf("%s WithHaveTruncated(%v)", s.folder, device)
|
||||||
s.db.withHave([]byte(s.folder), device[:], true, nativeFileIterator(fn))
|
s.db.withHave([]byte(s.folder), device[:], nil, true, nativeFileIterator(fn))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *FileSet) WithPrefixedHaveTruncated(device protocol.DeviceID, prefix string, fn Iterator) {
|
||||||
|
l.Debugf("%s WithPrefixedHaveTruncated(%v)", s.folder, device)
|
||||||
|
s.db.withHave([]byte(s.folder), device[:], []byte(prefix), true, nativeFileIterator(fn))
|
||||||
|
}
|
||||||
func (s *FileSet) WithGlobal(fn Iterator) {
|
func (s *FileSet) WithGlobal(fn Iterator) {
|
||||||
l.Debugf("%s WithGlobal()", s.folder)
|
l.Debugf("%s WithGlobal()", s.folder)
|
||||||
s.db.withGlobal([]byte(s.folder), nil, false, nativeFileIterator(fn))
|
s.db.withGlobal([]byte(s.folder), nil, false, nativeFileIterator(fn))
|
||||||
@@ -244,7 +248,7 @@ func DropFolder(db *Instance, folder string) {
|
|||||||
db.dropFolder([]byte(folder))
|
db.dropFolder([]byte(folder))
|
||||||
bm := &BlockMap{
|
bm := &BlockMap{
|
||||||
db: db,
|
db: db,
|
||||||
folder: db.folderIdx.ID([]byte(folder)),
|
folder: folder,
|
||||||
}
|
}
|
||||||
bm.Drop()
|
bm.Drop()
|
||||||
NewVirtualMtimeRepo(db, folder).Drop()
|
NewVirtualMtimeRepo(db, folder).Drop()
|
||||||
|
|||||||
Vendored
BIN
Binary file not shown.
+22
-20
@@ -7,6 +7,8 @@
|
|||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
"github.com/calmh/xdr"
|
"github.com/calmh/xdr"
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
)
|
)
|
||||||
@@ -16,32 +18,32 @@ type FileInfoTruncated struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *FileInfoTruncated) UnmarshalXDR(bs []byte) error {
|
func (o *FileInfoTruncated) UnmarshalXDR(bs []byte) error {
|
||||||
return o.UnmarshalXDRFrom(&xdr.Unmarshaller{Data: bs})
|
var br = bytes.NewReader(bs)
|
||||||
|
var xr = xdr.NewReader(br)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *FileInfoTruncated) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
|
func (o *FileInfoTruncated) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
o.Name = u.UnmarshalStringMax(8192)
|
o.Name = xr.ReadStringMax(8192)
|
||||||
o.Flags = u.UnmarshalUint32()
|
o.Flags = xr.ReadUint32()
|
||||||
o.Modified = int64(u.UnmarshalUint64())
|
o.Modified = int64(xr.ReadUint64())
|
||||||
(&o.Version).UnmarshalXDRFrom(u)
|
(&o.Version).DecodeXDRFrom(xr)
|
||||||
o.LocalVersion = int64(u.UnmarshalUint64())
|
o.LocalVersion = int64(xr.ReadUint64())
|
||||||
_BlocksSize := int(u.UnmarshalUint32())
|
_BlocksSize := int(xr.ReadUint32())
|
||||||
if _BlocksSize < 0 {
|
if _BlocksSize < 0 {
|
||||||
return xdr.ElementSizeExceeded("Blocks", _BlocksSize, 1000000)
|
return xdr.ElementSizeExceeded("Blocks", _BlocksSize, 1000000)
|
||||||
} else if _BlocksSize == 0 {
|
}
|
||||||
o.Blocks = nil
|
if _BlocksSize > 1000000 {
|
||||||
} else {
|
return xdr.ElementSizeExceeded("Blocks", _BlocksSize, 1000000)
|
||||||
if _BlocksSize > 1000000 {
|
|
||||||
return xdr.ElementSizeExceeded("Blocks", _BlocksSize, 1000000)
|
|
||||||
}
|
|
||||||
for i := 0; i < _BlocksSize; i++ {
|
|
||||||
size := int64(u.UnmarshalUint32())
|
|
||||||
o.CachedSize += size
|
|
||||||
u.UnmarshalBytes()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return u.Error
|
buf := make([]byte, 64)
|
||||||
|
for i := 0; i < _BlocksSize; i++ {
|
||||||
|
size := xr.ReadUint32()
|
||||||
|
o.CachedSize += int64(size)
|
||||||
|
xr.ReadBytesMaxInto(64, buf)
|
||||||
|
}
|
||||||
|
return xr.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
func BlocksToSize(num int) int64 {
|
func BlocksToSize(num int) int64 {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -25,12 +24,10 @@ type VirtualMtimeRepo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewVirtualMtimeRepo(ldb *Instance, folder string) *VirtualMtimeRepo {
|
func NewVirtualMtimeRepo(ldb *Instance, folder string) *VirtualMtimeRepo {
|
||||||
var prefix [5]byte // key type + 4 bytes folder idx number
|
prefix := string(KeyTypeVirtualMtime) + folder
|
||||||
prefix[0] = KeyTypeVirtualMtime
|
|
||||||
binary.BigEndian.PutUint32(prefix[1:], ldb.folderIdx.ID([]byte(folder)))
|
|
||||||
|
|
||||||
return &VirtualMtimeRepo{
|
return &VirtualMtimeRepo{
|
||||||
ns: NewNamespacedKV(ldb, string(prefix[:])),
|
ns: NewNamespacedKV(ldb, prefix),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+164
-124
@@ -5,6 +5,9 @@
|
|||||||
package discover
|
package discover
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
|
||||||
"github.com/calmh/xdr"
|
"github.com/calmh/xdr"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -37,16 +40,13 @@ struct Announce {
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func (o Announce) XDRSize() int {
|
func (o Announce) EncodeXDR(w io.Writer) (int, error) {
|
||||||
return 4 +
|
var xw = xdr.NewWriter(w)
|
||||||
o.This.XDRSize() +
|
return o.EncodeXDRInto(xw)
|
||||||
4 + xdr.SizeOfSlice(o.Extra)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Announce) MarshalXDR() ([]byte, error) {
|
func (o Announce) MarshalXDR() ([]byte, error) {
|
||||||
buf := make([]byte, o.XDRSize())
|
return o.AppendXDR(make([]byte, 0, 128))
|
||||||
m := &xdr.Marshaller{Data: buf}
|
|
||||||
return buf, o.MarshalXDRInto(m)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Announce) MustMarshalXDR() []byte {
|
func (o Announce) MustMarshalXDR() []byte {
|
||||||
@@ -57,49 +57,58 @@ func (o Announce) MustMarshalXDR() []byte {
|
|||||||
return bs
|
return bs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Announce) MarshalXDRInto(m *xdr.Marshaller) error {
|
func (o Announce) AppendXDR(bs []byte) ([]byte, error) {
|
||||||
m.MarshalUint32(o.Magic)
|
var aw = xdr.AppendWriter(bs)
|
||||||
if err := o.This.MarshalXDRInto(m); err != nil {
|
var xw = xdr.NewWriter(&aw)
|
||||||
return err
|
_, err := o.EncodeXDRInto(xw)
|
||||||
|
return []byte(aw), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Announce) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
|
xw.WriteUint32(o.Magic)
|
||||||
|
_, err := o.This.EncodeXDRInto(xw)
|
||||||
|
if err != nil {
|
||||||
|
return xw.Tot(), err
|
||||||
}
|
}
|
||||||
if l := len(o.Extra); l > 16 {
|
if l := len(o.Extra); l > 16 {
|
||||||
return xdr.ElementSizeExceeded("Extra", l, 16)
|
return xw.Tot(), xdr.ElementSizeExceeded("Extra", l, 16)
|
||||||
}
|
}
|
||||||
m.MarshalUint32(uint32(len(o.Extra)))
|
xw.WriteUint32(uint32(len(o.Extra)))
|
||||||
for i := range o.Extra {
|
for i := range o.Extra {
|
||||||
if err := o.Extra[i].MarshalXDRInto(m); err != nil {
|
_, err := o.Extra[i].EncodeXDRInto(xw)
|
||||||
return err
|
if err != nil {
|
||||||
|
return xw.Tot(), err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return m.Error
|
return xw.Tot(), xw.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Announce) DecodeXDR(r io.Reader) error {
|
||||||
|
xr := xdr.NewReader(r)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Announce) UnmarshalXDR(bs []byte) error {
|
func (o *Announce) UnmarshalXDR(bs []byte) error {
|
||||||
u := &xdr.Unmarshaller{Data: bs}
|
var br = bytes.NewReader(bs)
|
||||||
return o.UnmarshalXDRFrom(u)
|
var xr = xdr.NewReader(br)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
}
|
}
|
||||||
func (o *Announce) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
|
|
||||||
o.Magic = u.UnmarshalUint32()
|
func (o *Announce) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
(&o.This).UnmarshalXDRFrom(u)
|
o.Magic = xr.ReadUint32()
|
||||||
_ExtraSize := int(u.UnmarshalUint32())
|
(&o.This).DecodeXDRFrom(xr)
|
||||||
|
_ExtraSize := int(xr.ReadUint32())
|
||||||
if _ExtraSize < 0 {
|
if _ExtraSize < 0 {
|
||||||
return xdr.ElementSizeExceeded("Extra", _ExtraSize, 16)
|
return xdr.ElementSizeExceeded("Extra", _ExtraSize, 16)
|
||||||
} else if _ExtraSize == 0 {
|
|
||||||
o.Extra = nil
|
|
||||||
} else {
|
|
||||||
if _ExtraSize > 16 {
|
|
||||||
return xdr.ElementSizeExceeded("Extra", _ExtraSize, 16)
|
|
||||||
}
|
|
||||||
if _ExtraSize <= len(o.Extra) {
|
|
||||||
o.Extra = o.Extra[:_ExtraSize]
|
|
||||||
} else {
|
|
||||||
o.Extra = make([]Device, _ExtraSize)
|
|
||||||
}
|
|
||||||
for i := range o.Extra {
|
|
||||||
(&o.Extra[i]).UnmarshalXDRFrom(u)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return u.Error
|
if _ExtraSize > 16 {
|
||||||
|
return xdr.ElementSizeExceeded("Extra", _ExtraSize, 16)
|
||||||
|
}
|
||||||
|
o.Extra = make([]Device, _ExtraSize)
|
||||||
|
for i := range o.Extra {
|
||||||
|
(&o.Extra[i]).DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
return xr.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -109,8 +118,10 @@ Device Structure:
|
|||||||
0 1 2 3
|
0 1 2 3
|
||||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Length of ID |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
/ /
|
/ /
|
||||||
\ ID (length + padded data) \
|
\ ID (variable length) \
|
||||||
/ /
|
/ /
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Number of Addresses |
|
| Number of Addresses |
|
||||||
@@ -135,16 +146,13 @@ struct Device {
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func (o Device) XDRSize() int {
|
func (o Device) EncodeXDR(w io.Writer) (int, error) {
|
||||||
return 4 + len(o.ID) + xdr.Padding(len(o.ID)) +
|
var xw = xdr.NewWriter(w)
|
||||||
4 + xdr.SizeOfSlice(o.Addresses) +
|
return o.EncodeXDRInto(xw)
|
||||||
4 + xdr.SizeOfSlice(o.Relays)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Device) MarshalXDR() ([]byte, error) {
|
func (o Device) MarshalXDR() ([]byte, error) {
|
||||||
buf := make([]byte, o.XDRSize())
|
return o.AppendXDR(make([]byte, 0, 128))
|
||||||
m := &xdr.Marshaller{Data: buf}
|
|
||||||
return buf, o.MarshalXDRInto(m)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Device) MustMarshalXDR() []byte {
|
func (o Device) MustMarshalXDR() []byte {
|
||||||
@@ -155,75 +163,77 @@ func (o Device) MustMarshalXDR() []byte {
|
|||||||
return bs
|
return bs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Device) MarshalXDRInto(m *xdr.Marshaller) error {
|
func (o Device) AppendXDR(bs []byte) ([]byte, error) {
|
||||||
|
var aw = xdr.AppendWriter(bs)
|
||||||
|
var xw = xdr.NewWriter(&aw)
|
||||||
|
_, err := o.EncodeXDRInto(xw)
|
||||||
|
return []byte(aw), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Device) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
if l := len(o.ID); l > 32 {
|
if l := len(o.ID); l > 32 {
|
||||||
return xdr.ElementSizeExceeded("ID", l, 32)
|
return xw.Tot(), xdr.ElementSizeExceeded("ID", l, 32)
|
||||||
}
|
}
|
||||||
m.MarshalBytes(o.ID)
|
xw.WriteBytes(o.ID)
|
||||||
if l := len(o.Addresses); l > 16 {
|
if l := len(o.Addresses); l > 16 {
|
||||||
return xdr.ElementSizeExceeded("Addresses", l, 16)
|
return xw.Tot(), xdr.ElementSizeExceeded("Addresses", l, 16)
|
||||||
}
|
}
|
||||||
m.MarshalUint32(uint32(len(o.Addresses)))
|
xw.WriteUint32(uint32(len(o.Addresses)))
|
||||||
for i := range o.Addresses {
|
for i := range o.Addresses {
|
||||||
if err := o.Addresses[i].MarshalXDRInto(m); err != nil {
|
_, err := o.Addresses[i].EncodeXDRInto(xw)
|
||||||
return err
|
if err != nil {
|
||||||
|
return xw.Tot(), err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if l := len(o.Relays); l > 16 {
|
if l := len(o.Relays); l > 16 {
|
||||||
return xdr.ElementSizeExceeded("Relays", l, 16)
|
return xw.Tot(), xdr.ElementSizeExceeded("Relays", l, 16)
|
||||||
}
|
}
|
||||||
m.MarshalUint32(uint32(len(o.Relays)))
|
xw.WriteUint32(uint32(len(o.Relays)))
|
||||||
for i := range o.Relays {
|
for i := range o.Relays {
|
||||||
if err := o.Relays[i].MarshalXDRInto(m); err != nil {
|
_, err := o.Relays[i].EncodeXDRInto(xw)
|
||||||
return err
|
if err != nil {
|
||||||
|
return xw.Tot(), err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return m.Error
|
return xw.Tot(), xw.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Device) DecodeXDR(r io.Reader) error {
|
||||||
|
xr := xdr.NewReader(r)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Device) UnmarshalXDR(bs []byte) error {
|
func (o *Device) UnmarshalXDR(bs []byte) error {
|
||||||
u := &xdr.Unmarshaller{Data: bs}
|
var br = bytes.NewReader(bs)
|
||||||
return o.UnmarshalXDRFrom(u)
|
var xr = xdr.NewReader(br)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
}
|
}
|
||||||
func (o *Device) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
|
|
||||||
o.ID = u.UnmarshalBytesMax(32)
|
func (o *Device) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
_AddressesSize := int(u.UnmarshalUint32())
|
o.ID = xr.ReadBytesMax(32)
|
||||||
|
_AddressesSize := int(xr.ReadUint32())
|
||||||
if _AddressesSize < 0 {
|
if _AddressesSize < 0 {
|
||||||
return xdr.ElementSizeExceeded("Addresses", _AddressesSize, 16)
|
return xdr.ElementSizeExceeded("Addresses", _AddressesSize, 16)
|
||||||
} else if _AddressesSize == 0 {
|
|
||||||
o.Addresses = nil
|
|
||||||
} else {
|
|
||||||
if _AddressesSize > 16 {
|
|
||||||
return xdr.ElementSizeExceeded("Addresses", _AddressesSize, 16)
|
|
||||||
}
|
|
||||||
if _AddressesSize <= len(o.Addresses) {
|
|
||||||
o.Addresses = o.Addresses[:_AddressesSize]
|
|
||||||
} else {
|
|
||||||
o.Addresses = make([]Address, _AddressesSize)
|
|
||||||
}
|
|
||||||
for i := range o.Addresses {
|
|
||||||
(&o.Addresses[i]).UnmarshalXDRFrom(u)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_RelaysSize := int(u.UnmarshalUint32())
|
if _AddressesSize > 16 {
|
||||||
|
return xdr.ElementSizeExceeded("Addresses", _AddressesSize, 16)
|
||||||
|
}
|
||||||
|
o.Addresses = make([]Address, _AddressesSize)
|
||||||
|
for i := range o.Addresses {
|
||||||
|
(&o.Addresses[i]).DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
_RelaysSize := int(xr.ReadUint32())
|
||||||
if _RelaysSize < 0 {
|
if _RelaysSize < 0 {
|
||||||
return xdr.ElementSizeExceeded("Relays", _RelaysSize, 16)
|
return xdr.ElementSizeExceeded("Relays", _RelaysSize, 16)
|
||||||
} else if _RelaysSize == 0 {
|
|
||||||
o.Relays = nil
|
|
||||||
} else {
|
|
||||||
if _RelaysSize > 16 {
|
|
||||||
return xdr.ElementSizeExceeded("Relays", _RelaysSize, 16)
|
|
||||||
}
|
|
||||||
if _RelaysSize <= len(o.Relays) {
|
|
||||||
o.Relays = o.Relays[:_RelaysSize]
|
|
||||||
} else {
|
|
||||||
o.Relays = make([]Relay, _RelaysSize)
|
|
||||||
}
|
|
||||||
for i := range o.Relays {
|
|
||||||
(&o.Relays[i]).UnmarshalXDRFrom(u)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return u.Error
|
if _RelaysSize > 16 {
|
||||||
|
return xdr.ElementSizeExceeded("Relays", _RelaysSize, 16)
|
||||||
|
}
|
||||||
|
o.Relays = make([]Relay, _RelaysSize)
|
||||||
|
for i := range o.Relays {
|
||||||
|
(&o.Relays[i]).DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
return xr.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -233,8 +243,10 @@ Address Structure:
|
|||||||
0 1 2 3
|
0 1 2 3
|
||||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Length of URL |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
/ /
|
/ /
|
||||||
\ URL (length + padded data) \
|
\ URL (variable length) \
|
||||||
/ /
|
/ /
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
@@ -245,14 +257,13 @@ struct Address {
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func (o Address) XDRSize() int {
|
func (o Address) EncodeXDR(w io.Writer) (int, error) {
|
||||||
return 4 + len(o.URL) + xdr.Padding(len(o.URL))
|
var xw = xdr.NewWriter(w)
|
||||||
|
return o.EncodeXDRInto(xw)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Address) MarshalXDR() ([]byte, error) {
|
func (o Address) MarshalXDR() ([]byte, error) {
|
||||||
buf := make([]byte, o.XDRSize())
|
return o.AppendXDR(make([]byte, 0, 128))
|
||||||
m := &xdr.Marshaller{Data: buf}
|
|
||||||
return buf, o.MarshalXDRInto(m)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Address) MustMarshalXDR() []byte {
|
func (o Address) MustMarshalXDR() []byte {
|
||||||
@@ -263,21 +274,35 @@ func (o Address) MustMarshalXDR() []byte {
|
|||||||
return bs
|
return bs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Address) MarshalXDRInto(m *xdr.Marshaller) error {
|
func (o Address) AppendXDR(bs []byte) ([]byte, error) {
|
||||||
|
var aw = xdr.AppendWriter(bs)
|
||||||
|
var xw = xdr.NewWriter(&aw)
|
||||||
|
_, err := o.EncodeXDRInto(xw)
|
||||||
|
return []byte(aw), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Address) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
if l := len(o.URL); l > 2083 {
|
if l := len(o.URL); l > 2083 {
|
||||||
return xdr.ElementSizeExceeded("URL", l, 2083)
|
return xw.Tot(), xdr.ElementSizeExceeded("URL", l, 2083)
|
||||||
}
|
}
|
||||||
m.MarshalString(o.URL)
|
xw.WriteString(o.URL)
|
||||||
return m.Error
|
return xw.Tot(), xw.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Address) DecodeXDR(r io.Reader) error {
|
||||||
|
xr := xdr.NewReader(r)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Address) UnmarshalXDR(bs []byte) error {
|
func (o *Address) UnmarshalXDR(bs []byte) error {
|
||||||
u := &xdr.Unmarshaller{Data: bs}
|
var br = bytes.NewReader(bs)
|
||||||
return o.UnmarshalXDRFrom(u)
|
var xr = xdr.NewReader(br)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
}
|
}
|
||||||
func (o *Address) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
|
|
||||||
o.URL = u.UnmarshalStringMax(2083)
|
func (o *Address) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
return u.Error
|
o.URL = xr.ReadStringMax(2083)
|
||||||
|
return xr.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -287,8 +312,10 @@ Relay Structure:
|
|||||||
0 1 2 3
|
0 1 2 3
|
||||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Length of URL |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
/ /
|
/ /
|
||||||
\ URL (length + padded data) \
|
\ URL (variable length) \
|
||||||
/ /
|
/ /
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Latency |
|
| Latency |
|
||||||
@@ -302,14 +329,13 @@ struct Relay {
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func (o Relay) XDRSize() int {
|
func (o Relay) EncodeXDR(w io.Writer) (int, error) {
|
||||||
return 4 + len(o.URL) + xdr.Padding(len(o.URL)) + 4
|
var xw = xdr.NewWriter(w)
|
||||||
|
return o.EncodeXDRInto(xw)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Relay) MarshalXDR() ([]byte, error) {
|
func (o Relay) MarshalXDR() ([]byte, error) {
|
||||||
buf := make([]byte, o.XDRSize())
|
return o.AppendXDR(make([]byte, 0, 128))
|
||||||
m := &xdr.Marshaller{Data: buf}
|
|
||||||
return buf, o.MarshalXDRInto(m)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Relay) MustMarshalXDR() []byte {
|
func (o Relay) MustMarshalXDR() []byte {
|
||||||
@@ -320,21 +346,35 @@ func (o Relay) MustMarshalXDR() []byte {
|
|||||||
return bs
|
return bs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Relay) MarshalXDRInto(m *xdr.Marshaller) error {
|
func (o Relay) AppendXDR(bs []byte) ([]byte, error) {
|
||||||
|
var aw = xdr.AppendWriter(bs)
|
||||||
|
var xw = xdr.NewWriter(&aw)
|
||||||
|
_, err := o.EncodeXDRInto(xw)
|
||||||
|
return []byte(aw), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Relay) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
if l := len(o.URL); l > 2083 {
|
if l := len(o.URL); l > 2083 {
|
||||||
return xdr.ElementSizeExceeded("URL", l, 2083)
|
return xw.Tot(), xdr.ElementSizeExceeded("URL", l, 2083)
|
||||||
}
|
}
|
||||||
m.MarshalString(o.URL)
|
xw.WriteString(o.URL)
|
||||||
m.MarshalUint32(uint32(o.Latency))
|
xw.WriteUint32(uint32(o.Latency))
|
||||||
return m.Error
|
return xw.Tot(), xw.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Relay) DecodeXDR(r io.Reader) error {
|
||||||
|
xr := xdr.NewReader(r)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Relay) UnmarshalXDR(bs []byte) error {
|
func (o *Relay) UnmarshalXDR(bs []byte) error {
|
||||||
u := &xdr.Unmarshaller{Data: bs}
|
var br = bytes.NewReader(bs)
|
||||||
return o.UnmarshalXDRFrom(u)
|
var xr = xdr.NewReader(br)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
}
|
}
|
||||||
func (o *Relay) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
|
|
||||||
o.URL = u.UnmarshalStringMax(2083)
|
func (o *Relay) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
o.Latency = int32(u.UnmarshalUint32())
|
o.URL = xr.ReadStringMax(2083)
|
||||||
return u.Error
|
o.Latency = int32(xr.ReadUint32())
|
||||||
|
return xr.Error()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ const (
|
|||||||
LevelDebug LogLevel = iota
|
LevelDebug LogLevel = iota
|
||||||
LevelVerbose
|
LevelVerbose
|
||||||
LevelInfo
|
LevelInfo
|
||||||
|
LevelOK
|
||||||
LevelWarn
|
LevelWarn
|
||||||
LevelFatal
|
LevelFatal
|
||||||
NumLevels
|
NumLevels
|
||||||
@@ -41,6 +42,8 @@ type Logger interface {
|
|||||||
Verbosef(format string, vals ...interface{})
|
Verbosef(format string, vals ...interface{})
|
||||||
Infoln(vals ...interface{})
|
Infoln(vals ...interface{})
|
||||||
Infof(format string, vals ...interface{})
|
Infof(format string, vals ...interface{})
|
||||||
|
Okln(vals ...interface{})
|
||||||
|
Okf(format string, vals ...interface{})
|
||||||
Warnln(vals ...interface{})
|
Warnln(vals ...interface{})
|
||||||
Warnf(format string, vals ...interface{})
|
Warnf(format string, vals ...interface{})
|
||||||
Fatalln(vals ...interface{})
|
Fatalln(vals ...interface{})
|
||||||
@@ -162,6 +165,24 @@ func (l *logger) Infof(format string, vals ...interface{}) {
|
|||||||
l.callHandlers(LevelInfo, s)
|
l.callHandlers(LevelInfo, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Okln logs a line with an OK prefix.
|
||||||
|
func (l *logger) Okln(vals ...interface{}) {
|
||||||
|
l.mut.Lock()
|
||||||
|
defer l.mut.Unlock()
|
||||||
|
s := fmt.Sprintln(vals...)
|
||||||
|
l.logger.Output(2, "OK: "+s)
|
||||||
|
l.callHandlers(LevelOK, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Okf logs a formatted line with an OK prefix.
|
||||||
|
func (l *logger) Okf(format string, vals ...interface{}) {
|
||||||
|
l.mut.Lock()
|
||||||
|
defer l.mut.Unlock()
|
||||||
|
s := fmt.Sprintf(format, vals...)
|
||||||
|
l.logger.Output(2, "OK: "+s)
|
||||||
|
l.callHandlers(LevelOK, s)
|
||||||
|
}
|
||||||
|
|
||||||
// Warnln logs a formatted line with a WARNING prefix.
|
// Warnln logs a formatted line with a WARNING prefix.
|
||||||
func (l *logger) Warnln(vals ...interface{}) {
|
func (l *logger) Warnln(vals ...interface{}) {
|
||||||
l.mut.Lock()
|
l.mut.Lock()
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ func TestAPI(t *testing.T) {
|
|||||||
l.AddHandler(LevelDebug, checkFunc(t, LevelDebug, &debug))
|
l.AddHandler(LevelDebug, checkFunc(t, LevelDebug, &debug))
|
||||||
info := 0
|
info := 0
|
||||||
l.AddHandler(LevelInfo, checkFunc(t, LevelInfo, &info))
|
l.AddHandler(LevelInfo, checkFunc(t, LevelInfo, &info))
|
||||||
|
ok := 0
|
||||||
|
l.AddHandler(LevelOK, checkFunc(t, LevelOK, &ok))
|
||||||
warn := 0
|
warn := 0
|
||||||
l.AddHandler(LevelWarn, checkFunc(t, LevelWarn, &warn))
|
l.AddHandler(LevelWarn, checkFunc(t, LevelWarn, &warn))
|
||||||
|
|
||||||
@@ -26,15 +28,20 @@ func TestAPI(t *testing.T) {
|
|||||||
l.Debugln("test", 0)
|
l.Debugln("test", 0)
|
||||||
l.Infof("test %d", 1)
|
l.Infof("test %d", 1)
|
||||||
l.Infoln("test", 1)
|
l.Infoln("test", 1)
|
||||||
|
l.Okf("test %d", 2)
|
||||||
|
l.Okln("test", 2)
|
||||||
l.Warnf("test %d", 3)
|
l.Warnf("test %d", 3)
|
||||||
l.Warnln("test", 3)
|
l.Warnln("test", 3)
|
||||||
|
|
||||||
if debug != 6 {
|
if debug != 8 {
|
||||||
t.Errorf("Debug handler called %d != 8 times", debug)
|
t.Errorf("Debug handler called %d != 8 times", debug)
|
||||||
}
|
}
|
||||||
if info != 4 {
|
if info != 6 {
|
||||||
t.Errorf("Info handler called %d != 6 times", info)
|
t.Errorf("Info handler called %d != 6 times", info)
|
||||||
}
|
}
|
||||||
|
if ok != 4 {
|
||||||
|
t.Errorf("Ok handler called %d != 4 times", ok)
|
||||||
|
}
|
||||||
if warn != 2 {
|
if warn != 2 {
|
||||||
t.Errorf("Warn handler called %d != 2 times", warn)
|
t.Errorf("Warn handler called %d != 2 times", warn)
|
||||||
}
|
}
|
||||||
|
|||||||
+102
-84
@@ -18,6 +18,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
stdsync "sync"
|
stdsync "sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -189,7 +190,7 @@ func (m *Model) StartFolderRW(folder string) {
|
|||||||
m.folderRunnerTokens[folder] = append(m.folderRunnerTokens[folder], token)
|
m.folderRunnerTokens[folder] = append(m.folderRunnerTokens[folder], token)
|
||||||
m.fmut.Unlock()
|
m.fmut.Unlock()
|
||||||
|
|
||||||
l.Infoln("Ready to synchronize", folder, "(read-write)")
|
l.Okln("Ready to synchronize", folder, "(read-write)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) warnAboutOverwritingProtectedFiles(folder string) {
|
func (m *Model) warnAboutOverwritingProtectedFiles(folder string) {
|
||||||
@@ -241,7 +242,7 @@ func (m *Model) StartFolderRO(folder string) {
|
|||||||
m.folderRunnerTokens[folder] = append(m.folderRunnerTokens[folder], token)
|
m.folderRunnerTokens[folder] = append(m.folderRunnerTokens[folder], token)
|
||||||
m.fmut.Unlock()
|
m.fmut.Unlock()
|
||||||
|
|
||||||
l.Infoln("Ready to synchronize", folder, "(read only; no external updates accepted)")
|
l.Okln("Ready to synchronize", folder, "(read only; no external updates accepted)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) RemoveFolder(folder string) {
|
func (m *Model) RemoveFolder(folder string) {
|
||||||
@@ -1318,28 +1319,13 @@ func (m *Model) internalScanFolderSubs(folder string, subs []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required to make sure that we start indexing at a directory we're already
|
// Clean the list of subitems to ensure that we start at a known
|
||||||
// aware off.
|
// directory, and don't scan subdirectories of things we've already
|
||||||
var unifySubs []string
|
// scanned.
|
||||||
nextSub:
|
subs = unifySubs(subs, func(f string) bool {
|
||||||
for _, sub := range subs {
|
_, ok := fs.Get(protocol.LocalDeviceID, f)
|
||||||
for sub != "" && sub != ".stfolder" && sub != ".stignore" {
|
return ok
|
||||||
if _, ok = fs.Get(protocol.LocalDeviceID, sub); ok {
|
})
|
||||||
break
|
|
||||||
}
|
|
||||||
sub = filepath.Dir(sub)
|
|
||||||
if sub == "." || sub == string(filepath.Separator) {
|
|
||||||
sub = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, us := range unifySubs {
|
|
||||||
if strings.HasPrefix(sub, us) {
|
|
||||||
continue nextSub
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unifySubs = append(unifySubs, sub)
|
|
||||||
}
|
|
||||||
subs = unifySubs
|
|
||||||
|
|
||||||
// The cancel channel is closed whenever we return (such as from an error),
|
// The cancel channel is closed whenever we return (such as from an error),
|
||||||
// to signal the potentially still running walker to stop.
|
// to signal the potentially still running walker to stop.
|
||||||
@@ -1405,76 +1391,69 @@ nextSub:
|
|||||||
m.updateLocals(folder, batch)
|
m.updateLocals(folder, batch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(subs) == 0 {
|
||||||
|
// If we have no specific subdirectories to traverse, set it to one
|
||||||
|
// empty prefix so we traverse the entire folder contents once.
|
||||||
|
subs = []string{""}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do a scan of the database for each prefix, to check for deleted files.
|
||||||
batch = batch[:0]
|
batch = batch[:0]
|
||||||
// TODO: We should limit the Have scanning to start at sub
|
for _, sub := range subs {
|
||||||
seenPrefix := false
|
var iterError error
|
||||||
var iterError error
|
|
||||||
fs.WithHaveTruncated(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
|
|
||||||
f := fi.(db.FileInfoTruncated)
|
|
||||||
hasPrefix := len(subs) == 0
|
|
||||||
for _, sub := range subs {
|
|
||||||
if strings.HasPrefix(f.Name, sub) {
|
|
||||||
hasPrefix = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Return true so that we keep iterating, until we get to the part
|
|
||||||
// of the tree we are interested in. Then return false so we stop
|
|
||||||
// iterating when we've passed the end of the subtree.
|
|
||||||
if !hasPrefix {
|
|
||||||
return !seenPrefix
|
|
||||||
}
|
|
||||||
|
|
||||||
seenPrefix = true
|
fs.WithPrefixedHaveTruncated(protocol.LocalDeviceID, sub, func(fi db.FileIntf) bool {
|
||||||
if !f.IsDeleted() {
|
f := fi.(db.FileInfoTruncated)
|
||||||
if f.IsInvalid() {
|
if !f.IsDeleted() {
|
||||||
return true
|
if f.IsInvalid() {
|
||||||
}
|
return true
|
||||||
|
|
||||||
if len(batch) == batchSizeFiles {
|
|
||||||
if err := m.CheckFolderHealth(folder); err != nil {
|
|
||||||
iterError = err
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
m.updateLocals(folder, batch)
|
|
||||||
batch = batch[:0]
|
|
||||||
}
|
|
||||||
|
|
||||||
if ignores.Match(f.Name) || symlinkInvalid(folder, f) {
|
if len(batch) == batchSizeFiles {
|
||||||
// File has been ignored or an unsupported symlink. Set invalid bit.
|
if err := m.CheckFolderHealth(folder); err != nil {
|
||||||
l.Debugln("setting invalid bit on ignored", f)
|
iterError = err
|
||||||
nf := protocol.FileInfo{
|
return false
|
||||||
Name: f.Name,
|
}
|
||||||
Flags: f.Flags | protocol.FlagInvalid,
|
m.updateLocals(folder, batch)
|
||||||
Modified: f.Modified,
|
batch = batch[:0]
|
||||||
Version: f.Version, // The file is still the same, so don't bump version
|
|
||||||
}
|
}
|
||||||
batch = append(batch, nf)
|
|
||||||
} else if _, err := osutil.Lstat(filepath.Join(folderCfg.Path(), f.Name)); err != nil {
|
|
||||||
// File has been deleted.
|
|
||||||
|
|
||||||
// We don't specifically verify that the error is
|
if ignores.Match(f.Name) || symlinkInvalid(folder, f) {
|
||||||
// os.IsNotExist because there is a corner case when a
|
// File has been ignored or an unsupported symlink. Set invalid bit.
|
||||||
// directory is suddenly transformed into a file. When that
|
l.Debugln("setting invalid bit on ignored", f)
|
||||||
// happens, files that were in the directory (that is now a
|
nf := protocol.FileInfo{
|
||||||
// file) are deleted but will return a confusing error ("not a
|
Name: f.Name,
|
||||||
// directory") when we try to Lstat() them.
|
Flags: f.Flags | protocol.FlagInvalid,
|
||||||
|
Modified: f.Modified,
|
||||||
|
Version: f.Version, // The file is still the same, so don't bump version
|
||||||
|
}
|
||||||
|
batch = append(batch, nf)
|
||||||
|
} else if _, err := osutil.Lstat(filepath.Join(folderCfg.Path(), f.Name)); err != nil {
|
||||||
|
// File has been deleted.
|
||||||
|
|
||||||
nf := protocol.FileInfo{
|
// We don't specifically verify that the error is
|
||||||
Name: f.Name,
|
// os.IsNotExist because there is a corner case when a
|
||||||
Flags: f.Flags | protocol.FlagDeleted,
|
// directory is suddenly transformed into a file. When that
|
||||||
Modified: f.Modified,
|
// happens, files that were in the directory (that is now a
|
||||||
Version: f.Version.Update(m.shortID),
|
// file) are deleted but will return a confusing error ("not a
|
||||||
|
// directory") when we try to Lstat() them.
|
||||||
|
|
||||||
|
nf := protocol.FileInfo{
|
||||||
|
Name: f.Name,
|
||||||
|
Flags: f.Flags | protocol.FlagDeleted,
|
||||||
|
Modified: f.Modified,
|
||||||
|
Version: f.Version.Update(m.shortID),
|
||||||
|
}
|
||||||
|
batch = append(batch, nf)
|
||||||
}
|
}
|
||||||
batch = append(batch, nf)
|
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
if iterError != nil {
|
||||||
|
l.Infof("Stopping folder %s mid-scan due to folder error: %s", folder, iterError)
|
||||||
|
return iterError
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
if iterError != nil {
|
|
||||||
l.Infof("Stopping folder %s mid-scan due to folder error: %s", folder, iterError)
|
|
||||||
return iterError
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := m.CheckFolderHealth(folder); err != nil {
|
if err := m.CheckFolderHealth(folder); err != nil {
|
||||||
@@ -2082,3 +2061,42 @@ func stringSliceWithout(ss []string, s string) []string {
|
|||||||
}
|
}
|
||||||
return ss
|
return ss
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unifySubs takes a list of files or directories and trims them down to
|
||||||
|
// themselves or the closest parent that exists() returns true for, while
|
||||||
|
// removing duplicates and subdirectories. That is, if we have foo/ in the
|
||||||
|
// list, we don't also need foo/bar/ because that's already covered.
|
||||||
|
func unifySubs(dirs []string, exists func(dir string) bool) []string {
|
||||||
|
var subs []string
|
||||||
|
|
||||||
|
// Trim each item to itself or its closest known parent
|
||||||
|
for _, sub := range dirs {
|
||||||
|
for sub != "" && sub != ".stfolder" && sub != ".stignore" {
|
||||||
|
if exists(sub) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
sub = filepath.Dir(sub)
|
||||||
|
if sub == "." || sub == string(filepath.Separator) {
|
||||||
|
// Shortcut. We are going to scan the full folder, so we can
|
||||||
|
// just return an empty list of subs at this point.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
subs = append(subs, sub)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove any paths that are already covered by their parent
|
||||||
|
sort.Strings(subs)
|
||||||
|
var cleaned []string
|
||||||
|
next:
|
||||||
|
for _, sub := range subs {
|
||||||
|
for _, existing := range cleaned {
|
||||||
|
if sub == existing || strings.HasPrefix(sub, existing+string(os.PathSeparator)) {
|
||||||
|
continue next
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cleaned = append(cleaned, sub)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cleaned
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -1210,3 +1212,89 @@ func TestIgnoreDelete(t *testing.T) {
|
|||||||
t.Fatal("foo should not be marked for deletion")
|
t.Fatal("foo should not be marked for deletion")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnifySubs(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
in []string // input to unifySubs
|
||||||
|
exists []string // paths that exist in the database
|
||||||
|
out []string // expected output
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
// trailing slashes are cleaned, known paths are just passed on
|
||||||
|
[]string{"foo/", "bar//"},
|
||||||
|
[]string{"foo", "bar"},
|
||||||
|
[]string{"bar", "foo"}, // the output is sorted
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// "foo/bar" gets trimmed as it's covered by foo
|
||||||
|
[]string{"foo", "bar/", "foo/bar/"},
|
||||||
|
[]string{"foo", "bar"},
|
||||||
|
[]string{"bar", "foo"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// "bar" gets trimmed to "" as it's unknown,
|
||||||
|
// "" gets simplified to the empty list
|
||||||
|
[]string{"foo", "bar", "foo/bar"},
|
||||||
|
[]string{"foo"},
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// two independent known paths, both are kept
|
||||||
|
// "usr/lib" is not a prefix of "usr/libexec"
|
||||||
|
[]string{"usr/lib", "usr/libexec"},
|
||||||
|
[]string{"usr/lib", "usr/libexec"},
|
||||||
|
[]string{"usr/lib", "usr/libexec"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// "usr/lib" is a prefix of "usr/lib/exec"
|
||||||
|
[]string{"usr/lib", "usr/lib/exec"},
|
||||||
|
[]string{"usr/lib", "usr/libexec"},
|
||||||
|
[]string{"usr/lib"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// .stignore and .stfolder are special and are passed on
|
||||||
|
// verbatim even though they are unknown
|
||||||
|
[]string{".stfolder", ".stignore"},
|
||||||
|
[]string{},
|
||||||
|
[]string{".stfolder", ".stignore"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// but the presense of something else unknown forces an actual
|
||||||
|
// scan
|
||||||
|
[]string{".stfolder", ".stignore", "foo/bar"},
|
||||||
|
[]string{},
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
// Fixup path separators
|
||||||
|
for i := range cases {
|
||||||
|
for j, p := range cases[i].in {
|
||||||
|
cases[i].in[j] = filepath.FromSlash(p)
|
||||||
|
}
|
||||||
|
for j, p := range cases[i].exists {
|
||||||
|
cases[i].exists[j] = filepath.FromSlash(p)
|
||||||
|
}
|
||||||
|
for j, p := range cases[i].out {
|
||||||
|
cases[i].out[j] = filepath.FromSlash(p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range cases {
|
||||||
|
exists := func(f string) bool {
|
||||||
|
for _, e := range tc.exists {
|
||||||
|
if f == e {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
out := unifySubs(tc.in, exists)
|
||||||
|
if !reflect.DeepEqual(tc.out, out) {
|
||||||
|
t.Errorf("Case %d failed; got %v, expected %v", i, out, tc.out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,16 +11,15 @@ type header struct {
|
|||||||
compression bool
|
compression bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h header) MarshalXDRInto(m *xdr.Marshaller) error {
|
func (h header) encodeXDR(xw *xdr.Writer) (int, error) {
|
||||||
v := encodeHeader(h)
|
u := encodeHeader(h)
|
||||||
m.MarshalUint32(v)
|
return xw.WriteUint32(u)
|
||||||
return m.Error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *header) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
|
func (h *header) decodeXDR(xr *xdr.Reader) error {
|
||||||
v := u.UnmarshalUint32()
|
u := xr.ReadUint32()
|
||||||
*h = decodeHeader(v)
|
*h = decodeHeader(u)
|
||||||
return u.Error
|
return xr.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeHeader(h header) uint32 {
|
func encodeHeader(h header) uint32 {
|
||||||
|
|||||||
+529
-435
File diff suppressed because it is too large
Load Diff
+21
-38
@@ -12,7 +12,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
lz4 "github.com/bkaradzic/go-lz4"
|
lz4 "github.com/bkaradzic/go-lz4"
|
||||||
"github.com/calmh/xdr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -131,7 +130,8 @@ type rawConnection struct {
|
|||||||
pool sync.Pool
|
pool sync.Pool
|
||||||
compression Compression
|
compression Compression
|
||||||
|
|
||||||
readerBuf []byte // used & reused by readMessage
|
rdbuf0 []byte // used & reused by readMessage
|
||||||
|
rdbuf1 []byte // used & reused by readMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
type asyncResult struct {
|
type asyncResult struct {
|
||||||
@@ -146,8 +146,7 @@ type hdrMsg struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type encodable interface {
|
type encodable interface {
|
||||||
MarshalXDRInto(m *xdr.Marshaller) error
|
AppendXDR([]byte) ([]byte, error)
|
||||||
XDRSize() int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type isEofer interface {
|
type isEofer interface {
|
||||||
@@ -375,14 +374,18 @@ func (c *rawConnection) readerLoop() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *rawConnection) readMessage() (hdr header, msg encodable, err error) {
|
func (c *rawConnection) readMessage() (hdr header, msg encodable, err error) {
|
||||||
hdrBuf := make([]byte, 8)
|
if cap(c.rdbuf0) < 8 {
|
||||||
_, err = io.ReadFull(c.cr, hdrBuf)
|
c.rdbuf0 = make([]byte, 8)
|
||||||
|
} else {
|
||||||
|
c.rdbuf0 = c.rdbuf0[:8]
|
||||||
|
}
|
||||||
|
_, err = io.ReadFull(c.cr, c.rdbuf0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr = decodeHeader(binary.BigEndian.Uint32(hdrBuf[:4]))
|
hdr = decodeHeader(binary.BigEndian.Uint32(c.rdbuf0[0:4]))
|
||||||
msglen := int(binary.BigEndian.Uint32(hdrBuf[4:]))
|
msglen := int(binary.BigEndian.Uint32(c.rdbuf0[4:8]))
|
||||||
|
|
||||||
l.Debugf("read header %v (msglen=%d)", hdr, msglen)
|
l.Debugf("read header %v (msglen=%d)", hdr, msglen)
|
||||||
|
|
||||||
@@ -396,40 +399,27 @@ func (c *rawConnection) readMessage() (hdr header, msg encodable, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// c.readerBuf contains a buffer we can reuse. But once we've unmarshalled
|
if cap(c.rdbuf0) < msglen {
|
||||||
// a message from the buffer we can't reuse it again as the unmarshalled
|
c.rdbuf0 = make([]byte, msglen)
|
||||||
// message refers to the contents of the buffer. The only case we a buffer
|
|
||||||
// ends up in readerBuf for reuse is when the message is compressed, as we
|
|
||||||
// then decompress into a new buffer instead.
|
|
||||||
|
|
||||||
var msgBuf []byte
|
|
||||||
if cap(c.readerBuf) >= msglen {
|
|
||||||
// If we have a buffer ready in rdbuf we just use that.
|
|
||||||
msgBuf = c.readerBuf[:msglen]
|
|
||||||
} else {
|
} else {
|
||||||
// Otherwise we allocate a new buffer.
|
c.rdbuf0 = c.rdbuf0[:msglen]
|
||||||
msgBuf = make([]byte, msglen)
|
|
||||||
}
|
}
|
||||||
|
_, err = io.ReadFull(c.cr, c.rdbuf0)
|
||||||
_, err = io.ReadFull(c.cr, msgBuf)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
l.Debugf("read %d bytes", len(msgBuf))
|
l.Debugf("read %d bytes", len(c.rdbuf0))
|
||||||
|
|
||||||
|
msgBuf := c.rdbuf0
|
||||||
if hdr.compression && msglen > 0 {
|
if hdr.compression && msglen > 0 {
|
||||||
// We're going to decompress msgBuf into a different newly allocated
|
c.rdbuf1 = c.rdbuf1[:cap(c.rdbuf1)]
|
||||||
// buffer, so keep msgBuf around for reuse on the next message.
|
c.rdbuf1, err = lz4.Decode(c.rdbuf1, c.rdbuf0)
|
||||||
c.readerBuf = msgBuf
|
|
||||||
|
|
||||||
msgBuf, err = lz4.Decode(nil, msgBuf)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
msgBuf = c.rdbuf1
|
||||||
l.Debugf("decompressed to %d bytes", len(msgBuf))
|
l.Debugf("decompressed to %d bytes", len(msgBuf))
|
||||||
} else {
|
|
||||||
c.readerBuf = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if shouldDebug() {
|
if shouldDebug() {
|
||||||
@@ -611,14 +601,7 @@ func (c *rawConnection) writerLoop() {
|
|||||||
case hm := <-c.outbox:
|
case hm := <-c.outbox:
|
||||||
if hm.msg != nil {
|
if hm.msg != nil {
|
||||||
// Uncompressed message in uncBuf
|
// Uncompressed message in uncBuf
|
||||||
msgLen := hm.msg.XDRSize()
|
uncBuf, err = hm.msg.AppendXDR(uncBuf[:0])
|
||||||
if cap(uncBuf) >= msgLen {
|
|
||||||
uncBuf = uncBuf[:msgLen]
|
|
||||||
} else {
|
|
||||||
uncBuf = make([]byte, msgLen)
|
|
||||||
}
|
|
||||||
m := &xdr.Marshaller{Data: uncBuf}
|
|
||||||
err = hm.msg.MarshalXDRInto(m)
|
|
||||||
if hm.done != nil {
|
if hm.done != nil {
|
||||||
close(hm.done)
|
close(hm.done)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
package protocol
|
package protocol
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@@ -54,13 +55,14 @@ func TestHeaderMarshalUnmarshal(t *testing.T) {
|
|||||||
ver = int(uint(ver) % 16)
|
ver = int(uint(ver) % 16)
|
||||||
id = int(uint(id) % 4096)
|
id = int(uint(id) % 4096)
|
||||||
typ = int(uint(typ) % 256)
|
typ = int(uint(typ) % 256)
|
||||||
buf := make([]byte, 4)
|
buf := new(bytes.Buffer)
|
||||||
|
xw := xdr.NewWriter(buf)
|
||||||
h0 := header{version: ver, msgID: id, msgType: typ}
|
h0 := header{version: ver, msgID: id, msgType: typ}
|
||||||
h0.MarshalXDRInto(&xdr.Marshaller{Data: buf})
|
h0.encodeXDR(xw)
|
||||||
|
|
||||||
|
xr := xdr.NewReader(buf)
|
||||||
var h1 header
|
var h1 header
|
||||||
h1.UnmarshalXDRFrom(&xdr.Unmarshaller{Data: buf})
|
h1.decodeXDR(xr)
|
||||||
return h0 == h1
|
return h0 == h1
|
||||||
}
|
}
|
||||||
if err := quick.Check(f, nil); err != nil {
|
if err := quick.Check(f, nil); err != nil {
|
||||||
@@ -126,7 +128,8 @@ func TestVersionErr(t *testing.T) {
|
|||||||
c0.ClusterConfig(ClusterConfigMessage{})
|
c0.ClusterConfig(ClusterConfigMessage{})
|
||||||
c1.ClusterConfig(ClusterConfigMessage{})
|
c1.ClusterConfig(ClusterConfigMessage{})
|
||||||
|
|
||||||
timeoutWriteHeader(c0.cw, header{
|
w := xdr.NewWriter(c0.cw)
|
||||||
|
timeoutWriteHeader(w, header{
|
||||||
version: 2, // higher than supported
|
version: 2, // higher than supported
|
||||||
msgID: 0,
|
msgID: 0,
|
||||||
msgType: messageTypeIndex,
|
msgType: messageTypeIndex,
|
||||||
@@ -151,7 +154,8 @@ func TestTypeErr(t *testing.T) {
|
|||||||
c0.ClusterConfig(ClusterConfigMessage{})
|
c0.ClusterConfig(ClusterConfigMessage{})
|
||||||
c1.ClusterConfig(ClusterConfigMessage{})
|
c1.ClusterConfig(ClusterConfigMessage{})
|
||||||
|
|
||||||
timeoutWriteHeader(c0.cw, header{
|
w := xdr.NewWriter(c0.cw)
|
||||||
|
timeoutWriteHeader(w, header{
|
||||||
version: 0,
|
version: 0,
|
||||||
msgID: 0,
|
msgID: 0,
|
||||||
msgType: 42, // unknown type
|
msgType: 42, // unknown type
|
||||||
@@ -201,7 +205,7 @@ func TestElementSizeExceededNested(t *testing.T) {
|
|||||||
m := ClusterConfigMessage{
|
m := ClusterConfigMessage{
|
||||||
ClientName: "longstringlongstringlongstringinglongstringlongstringlonlongstringlongstringlon",
|
ClientName: "longstringlongstringlongstringinglongstringlongstringlonlongstringlongstringlon",
|
||||||
}
|
}
|
||||||
_, err := m.MarshalXDR()
|
_, err := m.EncodeXDR(ioutil.Discard)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("ID length %d > max 64, but no error", len(m.Folders[0].ID))
|
t.Errorf("ID length %d > max 64, but no error", len(m.Folders[0].ID))
|
||||||
}
|
}
|
||||||
@@ -209,19 +213,12 @@ func TestElementSizeExceededNested(t *testing.T) {
|
|||||||
|
|
||||||
func TestMarshalIndexMessage(t *testing.T) {
|
func TestMarshalIndexMessage(t *testing.T) {
|
||||||
f := func(m1 IndexMessage) bool {
|
f := func(m1 IndexMessage) bool {
|
||||||
if len(m1.Options) == 0 {
|
|
||||||
m1.Options = nil
|
|
||||||
}
|
|
||||||
for i, f := range m1.Files {
|
for i, f := range m1.Files {
|
||||||
m1.Files[i].CachedSize = 0
|
m1.Files[i].CachedSize = 0
|
||||||
if len(f.Blocks) == 0 {
|
for j := range f.Blocks {
|
||||||
m1.Files[i].Blocks = nil
|
f.Blocks[j].Offset = 0
|
||||||
} else {
|
if len(f.Blocks[j].Hash) == 0 {
|
||||||
for j := range f.Blocks {
|
f.Blocks[j].Hash = nil
|
||||||
f.Blocks[j].Offset = 0
|
|
||||||
if len(f.Blocks[j].Hash) == 0 {
|
|
||||||
f.Blocks[j].Hash = nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -236,9 +233,6 @@ func TestMarshalIndexMessage(t *testing.T) {
|
|||||||
|
|
||||||
func TestMarshalRequestMessage(t *testing.T) {
|
func TestMarshalRequestMessage(t *testing.T) {
|
||||||
f := func(m1 RequestMessage) bool {
|
f := func(m1 RequestMessage) bool {
|
||||||
if len(m1.Options) == 0 {
|
|
||||||
m1.Options = nil
|
|
||||||
}
|
|
||||||
return testMarshal(t, "request", &m1, &RequestMessage{})
|
return testMarshal(t, "request", &m1, &RequestMessage{})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,9 +256,6 @@ func TestMarshalResponseMessage(t *testing.T) {
|
|||||||
|
|
||||||
func TestMarshalClusterConfigMessage(t *testing.T) {
|
func TestMarshalClusterConfigMessage(t *testing.T) {
|
||||||
f := func(m1 ClusterConfigMessage) bool {
|
f := func(m1 ClusterConfigMessage) bool {
|
||||||
if len(m1.Options) == 0 {
|
|
||||||
m1.Options = nil
|
|
||||||
}
|
|
||||||
return testMarshal(t, "clusterconfig", &m1, &ClusterConfigMessage{})
|
return testMarshal(t, "clusterconfig", &m1, &ClusterConfigMessage{})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,11 +275,13 @@ func TestMarshalCloseMessage(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type message interface {
|
type message interface {
|
||||||
MarshalXDR() ([]byte, error)
|
EncodeXDR(io.Writer) (int, error)
|
||||||
UnmarshalXDR([]byte) error
|
DecodeXDR(io.Reader) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func testMarshal(t *testing.T, prefix string, m1, m2 message) bool {
|
func testMarshal(t *testing.T, prefix string, m1, m2 message) bool {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
failed := func(bc []byte) {
|
failed := func(bc []byte) {
|
||||||
bs, _ := json.MarshalIndent(m1, "", " ")
|
bs, _ := json.MarshalIndent(m1, "", " ")
|
||||||
ioutil.WriteFile(prefix+"-1.txt", bs, 0644)
|
ioutil.WriteFile(prefix+"-1.txt", bs, 0644)
|
||||||
@@ -301,7 +294,7 @@ func testMarshal(t *testing.T, prefix string, m1, m2 message) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buf, err := m1.MarshalXDR()
|
_, err := m1.EncodeXDR(&buf)
|
||||||
if err != nil && strings.Contains(err.Error(), "exceeds size") {
|
if err != nil && strings.Contains(err.Error(), "exceeds size") {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -310,20 +303,23 @@ func testMarshal(t *testing.T, prefix string, m1, m2 message) bool {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = m2.UnmarshalXDR(buf)
|
bc := make([]byte, len(buf.Bytes()))
|
||||||
|
copy(bc, buf.Bytes())
|
||||||
|
|
||||||
|
err = m2.DecodeXDR(&buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
failed(buf)
|
failed(bc)
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ok := reflect.DeepEqual(m1, m2)
|
ok := reflect.DeepEqual(m1, m2)
|
||||||
if !ok {
|
if !ok {
|
||||||
failed(buf)
|
failed(bc)
|
||||||
}
|
}
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func timeoutWriteHeader(w io.Writer, hdr header) {
|
func timeoutWriteHeader(w *xdr.Writer, hdr header) {
|
||||||
// This tries to write a message header to w, but times out after a while.
|
// This tries to write a message header to w, but times out after a while.
|
||||||
// This is useful because in testing, with a PipeWriter, it will block
|
// This is useful because in testing, with a PipeWriter, it will block
|
||||||
// forever if the other side isn't reading any more. On the other hand we
|
// forever if the other side isn't reading any more. On the other hand we
|
||||||
@@ -336,7 +332,8 @@ func timeoutWriteHeader(w io.Writer, hdr header) {
|
|||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
w.Write(buf[:])
|
w.WriteRaw(buf[:])
|
||||||
|
l.Infoln("write completed")
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
|
|||||||
+24
-16
@@ -7,29 +7,37 @@ import "github.com/calmh/xdr"
|
|||||||
// This stuff is hacked up manually because genxdr doesn't support 'type
|
// This stuff is hacked up manually because genxdr doesn't support 'type
|
||||||
// Vector []Counter' declarations and it was tricky when I tried to add it...
|
// Vector []Counter' declarations and it was tricky when I tried to add it...
|
||||||
|
|
||||||
func (v Vector) MarshalXDRInto(m *xdr.Marshaller) error {
|
type xdrWriter interface {
|
||||||
m.MarshalUint32(uint32(len(v)))
|
WriteUint32(uint32) (int, error)
|
||||||
for i := range v {
|
WriteUint64(uint64) (int, error)
|
||||||
m.MarshalUint64(uint64(v[i].ID))
|
}
|
||||||
m.MarshalUint64(v[i].Value)
|
type xdrReader interface {
|
||||||
}
|
ReadUint32() uint32
|
||||||
return m.Error
|
ReadUint64() uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vector) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
|
// EncodeXDRInto encodes the vector as an XDR object into the given XDR
|
||||||
l := int(u.UnmarshalUint32())
|
// encoder.
|
||||||
|
func (v Vector) EncodeXDRInto(w xdrWriter) (int, error) {
|
||||||
|
w.WriteUint32(uint32(len(v)))
|
||||||
|
for i := range v {
|
||||||
|
w.WriteUint64(uint64(v[i].ID))
|
||||||
|
w.WriteUint64(v[i].Value)
|
||||||
|
}
|
||||||
|
return 4 + 16*len(v), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeXDRFrom decodes the XDR objects from the given reader into itself.
|
||||||
|
func (v *Vector) DecodeXDRFrom(r xdrReader) error {
|
||||||
|
l := int(r.ReadUint32())
|
||||||
if l > 1e6 {
|
if l > 1e6 {
|
||||||
return xdr.ElementSizeExceeded("number of counters", l, 1e6)
|
return xdr.ElementSizeExceeded("number of counters", l, 1e6)
|
||||||
}
|
}
|
||||||
n := make(Vector, l)
|
n := make(Vector, l)
|
||||||
for i := range n {
|
for i := range n {
|
||||||
n[i].ID = ShortID(u.UnmarshalUint64())
|
n[i].ID = ShortID(r.ReadUint64())
|
||||||
n[i].Value = u.UnmarshalUint64()
|
n[i].Value = r.ReadUint64()
|
||||||
}
|
}
|
||||||
*v = n
|
*v = n
|
||||||
return u.Error
|
return nil
|
||||||
}
|
|
||||||
|
|
||||||
func (v Vector) XDRSize() int {
|
|
||||||
return 4 + 16*len(v)
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user