mirror of
https://github.com/gogs/gogs.git
synced 2026-03-01 01:30:57 +01:00
Compare commits
137 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
599716bb1b | ||
|
|
ae88d76032 | ||
|
|
9266f28822 | ||
|
|
6488ee12be | ||
|
|
c2fb01a257 | ||
|
|
5761342f32 | ||
|
|
57af7432fc | ||
|
|
1c7dcdd6b9 | ||
|
|
25b3836418 | ||
|
|
5aa2bf86f4 | ||
|
|
b0eb47cb1c | ||
|
|
e7a4f96fb6 | ||
|
|
60110adc06 | ||
|
|
5ff2dfb23e | ||
|
|
eac32419fc | ||
|
|
e3d3d424b2 | ||
|
|
971e2c3bd6 | ||
|
|
c083d76567 | ||
|
|
52322ef624 | ||
|
|
a4ea3bd015 | ||
|
|
3d93532c87 | ||
|
|
fff615d5fc | ||
|
|
f1b8d52eb3 | ||
|
|
7ca5f8f119 | ||
|
|
194a742fb9 | ||
|
|
160956dd31 | ||
|
|
089bacd54e | ||
|
|
d950bf68e3 | ||
|
|
7796c9e122 | ||
|
|
528ec9bffd | ||
|
|
32ec4734f9 | ||
|
|
6a98e7d914 | ||
|
|
a752f09055 | ||
|
|
846bf2ca9f | ||
|
|
f4ab50501e | ||
|
|
de10387f41 | ||
|
|
1faaaeb3d9 | ||
|
|
12cb84b97f | ||
|
|
fdcca9292e | ||
|
|
a1f717f65a | ||
|
|
70a281a39b | ||
|
|
9fcf66f0e0 | ||
|
|
98b152030d | ||
|
|
467d7dacb6 | ||
|
|
d62ab49978 | ||
|
|
e30c701386 | ||
|
|
401bf944ef | ||
|
|
326c982660 | ||
|
|
4b25bdfbc4 | ||
|
|
528682a294 | ||
|
|
6aa00f7bcf | ||
|
|
f485fcde96 | ||
|
|
6f6b37f148 | ||
|
|
99c3a9390f | ||
|
|
f0df46c88a | ||
|
|
e84ac64964 | ||
|
|
3a30c06345 | ||
|
|
a10ca2c5f6 | ||
|
|
927d9f092b | ||
|
|
7938506e07 | ||
|
|
6f7276278d | ||
|
|
743d22669a | ||
|
|
84841c8c4b | ||
|
|
274a2ca528 | ||
|
|
d4aaef90e6 | ||
|
|
6efb1e5626 | ||
|
|
73b4acbb63 | ||
|
|
8a248696e9 | ||
|
|
8b35c194ec | ||
|
|
ac05f88641 | ||
|
|
4bbb878d20 | ||
|
|
2ce60ff314 | ||
|
|
17a4d8a5e5 | ||
|
|
04592c385b | ||
|
|
bc00da1721 | ||
|
|
76a0e43e88 | ||
|
|
24caccccdd | ||
|
|
26342b0c24 | ||
|
|
a4eaddff81 | ||
|
|
c041273dd3 | ||
|
|
fb970b9d87 | ||
|
|
0240f520ab | ||
|
|
3d105733a9 | ||
|
|
8df3ba96f3 | ||
|
|
d35a1c30f4 | ||
|
|
e9ae926e04 | ||
|
|
28c03f1147 | ||
|
|
84d9aff8a2 | ||
|
|
12d30255a7 | ||
|
|
7826eae452 | ||
|
|
8a2347592d | ||
|
|
bcd4adb3a0 | ||
|
|
bf5faf76eb | ||
|
|
f473895c41 | ||
|
|
fbf43c31e5 | ||
|
|
3c0c7a9f83 | ||
|
|
13216c5c20 | ||
|
|
6be9a2c1db | ||
|
|
d8612f7704 | ||
|
|
0a78d99a4d | ||
|
|
3df8eb60e3 | ||
|
|
0325bec283 | ||
|
|
dfad51fe9e | ||
|
|
7049cb9d97 | ||
|
|
78b8b63774 | ||
|
|
ba314a7a36 | ||
|
|
39356f4238 | ||
|
|
b3c05026df | ||
|
|
ce36fd7a49 | ||
|
|
69e00f9948 | ||
|
|
3257df0da3 | ||
|
|
0f2869069b | ||
|
|
a27c6f4b75 | ||
|
|
d27ca649c7 | ||
|
|
d9900e4dbc | ||
|
|
e75a1444af | ||
|
|
b35157f4ff | ||
|
|
762ab056a2 | ||
|
|
78481f0e42 | ||
|
|
746c7fd4e7 | ||
|
|
7f26ae0b45 | ||
|
|
b5948f2e71 | ||
|
|
79a1bfd963 | ||
|
|
ac53bb593d | ||
|
|
dd36c431ec | ||
|
|
b1d41cfa60 | ||
|
|
9dda9ef07c | ||
|
|
9a43fcb61c | ||
|
|
5ec8ef0230 | ||
|
|
d3db1b2591 | ||
|
|
3decc0b3d6 | ||
|
|
98b58fa050 | ||
|
|
5e11341232 | ||
|
|
90e93b1f3a | ||
|
|
e6f927f61a | ||
|
|
60ae8ac3d2 | ||
|
|
004fb30ebe |
@@ -1,7 +1,5 @@
|
||||
.git
|
||||
.git/**
|
||||
conf
|
||||
conf/**
|
||||
packager
|
||||
packager/**
|
||||
scripts
|
||||
@@ -9,13 +7,13 @@ scripts/**
|
||||
.github/
|
||||
.github/**
|
||||
config.codekit
|
||||
LICENSE
|
||||
Makefile
|
||||
.dockerignore
|
||||
*.yml
|
||||
*.md
|
||||
.bra.toml
|
||||
.editorconfig
|
||||
.gitignore
|
||||
.gopmfile
|
||||
Dockerfile*
|
||||
vendor
|
||||
vendor/**
|
||||
gogs
|
||||
|
||||
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
public/assets/* linguist-vendored
|
||||
public/plugins/* linguist-vendored
|
||||
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@@ -12,7 +12,7 @@ For bug reports, please give the relevant info:
|
||||
- [ ] MySQL
|
||||
- [ ] SQLite
|
||||
- Can you reproduce the bug at http://try.gogs.io:
|
||||
- [ ] Yes
|
||||
- [ ] Yes (provide example URL)
|
||||
- [ ] No
|
||||
- [ ] Not relevant
|
||||
- Log gist:
|
||||
|
||||
49
.gopmfile
49
.gopmfile
@@ -3,53 +3,54 @@ path = github.com/gogits/gogs
|
||||
|
||||
[deps]
|
||||
github.com/bradfitz/gomemcache = commit:fb1f79c
|
||||
github.com/codegangsta/cli = commit:aca5b04
|
||||
github.com/go-macaron/binding = commit:a68f342
|
||||
github.com/codegangsta/cli = commit:1efa31f
|
||||
github.com/go-macaron/binding = commit:9440f33
|
||||
github.com/go-macaron/cache = commit:5617353
|
||||
github.com/go-macaron/captcha = commit:8aa5919
|
||||
github.com/go-macaron/csrf = commit:6a9a7df
|
||||
github.com/go-macaron/gzip = commit:cad1c65
|
||||
github.com/go-macaron/i18n = commit:d2d3329
|
||||
github.com/go-macaron/i18n = commit:ef57533
|
||||
github.com/go-macaron/inject = commit:c5ab7bf
|
||||
github.com/go-macaron/session = commit:66031fc
|
||||
github.com/go-macaron/toolbox = commit:82b5115
|
||||
github.com/go-sql-driver/mysql = commit:66312f7
|
||||
github.com/go-xorm/core = commit:5021584
|
||||
github.com/go-xorm/xorm = commit:769f6b3
|
||||
github.com/go-sql-driver/mysql = commit:3654d25
|
||||
github.com/go-xorm/core = commit:bc1b7f8
|
||||
github.com/go-xorm/xorm = commit:b8b1711
|
||||
github.com/gogits/chardet = commit:2404f77
|
||||
github.com/gogits/cron = commit:3abc0f8
|
||||
github.com/gogits/git-module = commit:76e8cce
|
||||
github.com/gogits/go-gogs-client = commit:788ec59
|
||||
github.com/issue9/identicon = commit:f8c0d2c
|
||||
github.com/gogits/cron = commit:96040e4
|
||||
github.com/gogits/git-module = commit:53bcb73
|
||||
github.com/gogits/go-gogs-client = commit:ee68cd9
|
||||
github.com/issue9/identicon = commit:d36b545
|
||||
github.com/jaytaylor/html2text = commit:52d9b78
|
||||
github.com/kardianos/minwinsvc = commit:cad6b2b
|
||||
github.com/klauspost/compress = commit:006acde
|
||||
github.com/klauspost/compress = commit:14eb9c4
|
||||
github.com/klauspost/cpuid = commit:09cded8
|
||||
github.com/klauspost/crc32 = commit:19b0b33
|
||||
github.com/lib/pq = commit:165a352
|
||||
github.com/mattn/go-sqlite3 = commit:76e335f
|
||||
github.com/lib/pq = commit:ee1442b
|
||||
github.com/mattn/go-sqlite3 = commit:38ee283
|
||||
github.com/mcuadros/go-version = commit:d52711f
|
||||
github.com/microcosm-cc/bluemonday = commit:4ac6f27
|
||||
github.com/msteinert/pam = commit:02ccfbf
|
||||
github.com/nfnt/resize = commit:4d93a29
|
||||
github.com/russross/blackfriday = commit:b43df97
|
||||
github.com/satori/go.uuid = commit:e673fdd
|
||||
github.com/russross/blackfriday = commit:4e6f303
|
||||
github.com/satori/go.uuid = commit:879c588
|
||||
github.com/sergi/go-diff = commit:ec7fdbb
|
||||
github.com/shurcooL/sanitized_anchor_name = commit:10ef21a
|
||||
github.com/Unknwon/cae = commit:7f5e046
|
||||
github.com/Unknwon/com = commit:28b053d
|
||||
github.com/Unknwon/i18n = commit:3b48b66
|
||||
github.com/Unknwon/i18n = commit:39d6f27
|
||||
github.com/Unknwon/paginater = commit:7748a72
|
||||
golang.org/x/crypto = commit:c197bcf
|
||||
golang.org/x/net = commit:35b06af
|
||||
golang.org/x/sys = commit:9d4e42a
|
||||
golang.org/x/text = commit:1b466db
|
||||
golang.org/x/crypto = commit:77f4136
|
||||
golang.org/x/net = commit:3f122ce
|
||||
golang.org/x/sys = commit:7f918dd
|
||||
golang.org/x/text = commit:e477511
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 = commit:2caba25
|
||||
gopkg.in/asn1-ber.v1 = commit:4e86f43
|
||||
gopkg.in/bufio.v1 = commit:567b2bf
|
||||
gopkg.in/gomail.v2 = commit:060a5f4
|
||||
gopkg.in/ini.v1 = commit:776aa73
|
||||
gopkg.in/ldap.v2 = commit:07a7330
|
||||
gopkg.in/macaron.v1 = commit:94a5ef7
|
||||
gopkg.in/gomail.v2 = commit:81ebce5
|
||||
gopkg.in/ini.v1 = commit:72ba3e6
|
||||
gopkg.in/ldap.v2 = commit:0e7db8e
|
||||
gopkg.in/macaron.v1 = commit:2133042
|
||||
gopkg.in/redis.v2 = commit:e617904
|
||||
|
||||
[res]
|
||||
|
||||
@@ -2,9 +2,9 @@ FROM alpine:3.3
|
||||
MAINTAINER jp@roemer.im
|
||||
|
||||
# Install system utils & Gogs runtime dependencies
|
||||
ADD https://github.com/tianon/gosu/releases/download/1.7/gosu-amd64 /usr/sbin/gosu
|
||||
ADD https://github.com/tianon/gosu/releases/download/1.9/gosu-amd64 /usr/sbin/gosu
|
||||
RUN chmod +x /usr/sbin/gosu \
|
||||
&& apk --no-cache --no-progress add ca-certificates bash git linux-pam s6 curl openssh socat
|
||||
&& apk --no-cache --no-progress add ca-certificates bash git linux-pam s6 curl openssh socat tzdata
|
||||
|
||||
ENV GOGS_CUSTOM /data/gogs
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@ FROM hypriot/rpi-alpine-scratch:v3.2
|
||||
MAINTAINER jp@roemer.im, raxetul@gmail.com
|
||||
|
||||
# Install system utils & Gogs runtime dependencies
|
||||
ADD https://github.com/tianon/gosu/releases/download/1.7/gosu-armhf /usr/sbin/gosu
|
||||
ADD https://github.com/tianon/gosu/releases/download/1.9/gosu-armhf /usr/sbin/gosu
|
||||
RUN chmod +x /usr/sbin/gosu \
|
||||
&& echo "http://dl-4.alpinelinux.org/alpine/v3.3/main/" | tee /etc/apk/repositories \
|
||||
&& echo "http://dl-4.alpinelinux.org/alpine/v3.3/community/" | tee -a /etc/apk/repositories \
|
||||
&& apk -U --no-progress upgrade && rm -f /var/cache/apk/APKINDEX.* \
|
||||
&& apk --no-cache --no-progress add ca-certificates bash git linux-pam s6 curl openssh socat
|
||||
&& apk --no-cache --no-progress add ca-certificates bash git linux-pam s6 curl openssh socat tzdata
|
||||
|
||||
ENV GOGS_CUSTOM /data/gogs
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ Gogs - Go Git Service [
|
||||
|
||||
##### Current version: 0.9.13
|
||||
##### Current tip version: 0.9.48 (see [Releases](https://github.com/gogits/gogs/releases) for binary versions)
|
||||
|
||||
| Web | UI | Preview |
|
||||
|:-------------:|:-------:|:-------:|
|
||||
@@ -49,7 +49,7 @@ The goal of this project is to make the easiest, fastest, and most painless way
|
||||
- Mail service
|
||||
- Administration panel
|
||||
- Supports MySQL, PostgreSQL, SQLite3 and [TiDB](https://github.com/pingcap/tidb) (experimental)
|
||||
- Multi-language support ([15 languages](https://crowdin.com/project/gogs))
|
||||
- Multi-language support ([18 languages](https://crowdin.com/project/gogs))
|
||||
|
||||
## System Requirements
|
||||
|
||||
@@ -96,6 +96,7 @@ There are 5 ways to install Gogs:
|
||||
- [Sandstorm](https://github.com/cem/gogs-sandstorm)
|
||||
- [sloppy.io](https://github.com/sloppyio/quickstarters/tree/master/gogs)
|
||||
- [YunoHost](https://github.com/mbugeia/gogs_ynh)
|
||||
- [DPlatform](https://github.com/j8r/DPlatform)
|
||||
|
||||
## Software and Service Support
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
|
||||
- 支持邮件服务
|
||||
- 支持后台管理面板
|
||||
- 支持 MySQL、PostgreSQL、SQLite3 和 [TiDB](https://github.com/pingcap/tidb)(实验性支持) 数据库
|
||||
- 支持多语言本地化([15 种语言]([more](https://crowdin.com/project/gogs)))
|
||||
- 支持多语言本地化([18 种语言]([more](https://crowdin.com/project/gogs)))
|
||||
|
||||
## 系统要求
|
||||
|
||||
@@ -68,6 +68,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
|
||||
- [Sandstorm](https://github.com/cem/gogs-sandstorm)
|
||||
- [sloppy.io](https://github.com/sloppyio/quickstarters/tree/master/gogs)
|
||||
- [YunoHost](https://github.com/mbugeia/gogs_ynh)
|
||||
- [DPlatform](https://github.com/j8r/DPlatform)
|
||||
|
||||
## 软件及服务支持
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ func pemBlockForKey(priv interface{}) *pem.Block {
|
||||
case *ecdsa.PrivateKey:
|
||||
b, err := x509.MarshalECPrivateKey(k)
|
||||
if err != nil {
|
||||
log.Fatal("unable to marshal ECDSA private key: %v", err)
|
||||
log.Fatalf("Unable to marshal ECDSA private key: %v\n", err)
|
||||
}
|
||||
return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
|
||||
default:
|
||||
@@ -67,7 +67,7 @@ func pemBlockForKey(priv interface{}) *pem.Block {
|
||||
}
|
||||
}
|
||||
|
||||
func runCert(ctx *cli.Context) {
|
||||
func runCert(ctx *cli.Context) error {
|
||||
if len(ctx.String("host")) == 0 {
|
||||
log.Fatal("Missing required --host parameter")
|
||||
}
|
||||
@@ -153,9 +153,11 @@ func runCert(ctx *cli.Context) {
|
||||
|
||||
keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
log.Fatal("failed to open key.pem for writing: %v", err)
|
||||
log.Fatalf("Failed to open key.pem for writing: %v\n", err)
|
||||
}
|
||||
pem.Encode(keyOut, pemBlockForKey(priv))
|
||||
keyOut.Close()
|
||||
log.Println("Written key.pem")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -20,7 +20,9 @@ var CmdCert = cli.Command{
|
||||
Action: runCert,
|
||||
}
|
||||
|
||||
func runCert(ctx *cli.Context) {
|
||||
func runCert(ctx *cli.Context) error {
|
||||
fmt.Println("Command cert not available, please use build tags 'cert' to rebuild.")
|
||||
os.Exit(1)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
23
cmd/dump.go
23
cmd/dump.go
@@ -28,11 +28,12 @@ It can be used for backup and capture Gogs server image to send to maintainer`,
|
||||
Action: runDump,
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
|
||||
boolFlag("verbose, v", "show process details"),
|
||||
boolFlag("verbose, v", "Show process details"),
|
||||
stringFlag("tempdir, t", os.TempDir(), "Temporary dir path"),
|
||||
},
|
||||
}
|
||||
|
||||
func runDump(ctx *cli.Context) {
|
||||
func runDump(ctx *cli.Context) error {
|
||||
if ctx.IsSet("config") {
|
||||
setting.CustomConf = ctx.String("config")
|
||||
}
|
||||
@@ -40,7 +41,11 @@ func runDump(ctx *cli.Context) {
|
||||
models.LoadConfigs()
|
||||
models.SetEngine()
|
||||
|
||||
TmpWorkDir, err := ioutil.TempDir(os.TempDir(), "gogs-dump-")
|
||||
tmpDir := ctx.String("tempdir")
|
||||
if _, err := os.Stat(tmpDir); os.IsNotExist(err) {
|
||||
log.Fatalf("Path does not exist: %s", tmpDir)
|
||||
}
|
||||
TmpWorkDir, err := ioutil.TempDir(tmpDir, "gogs-dump-")
|
||||
if err != nil {
|
||||
log.Fatalf("Fail to create tmp work directory: %v", err)
|
||||
}
|
||||
@@ -68,21 +73,21 @@ func runDump(ctx *cli.Context) {
|
||||
log.Fatalf("Fail to create %s: %v", fileName, err)
|
||||
}
|
||||
|
||||
if err := z.AddFile("gogs-repo.zip", reposDump); err !=nil {
|
||||
if err := z.AddFile("gogs-repo.zip", reposDump); err != nil {
|
||||
log.Fatalf("Fail to include gogs-repo.zip: %v", err)
|
||||
}
|
||||
if err := z.AddFile("gogs-db.sql", dbDump); err !=nil {
|
||||
if err := z.AddFile("gogs-db.sql", dbDump); err != nil {
|
||||
log.Fatalf("Fail to include gogs-db.sql: %v", err)
|
||||
}
|
||||
customDir, err := os.Stat(setting.CustomPath)
|
||||
if err == nil && customDir.IsDir() {
|
||||
if err := z.AddDir("custom", setting.CustomPath); err !=nil {
|
||||
if err := z.AddDir("custom", setting.CustomPath); err != nil {
|
||||
log.Fatalf("Fail to include custom: %v", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Printf("Custom dir %s doesn't exist, skipped", setting.CustomPath)
|
||||
}
|
||||
if err := z.AddDir("log", setting.LogRootPath); err !=nil {
|
||||
if err := z.AddDir("log", setting.LogRootPath); err != nil {
|
||||
log.Fatalf("Fail to include log: %v", err)
|
||||
}
|
||||
// FIXME: SSH key file.
|
||||
@@ -94,4 +99,6 @@ func runDump(ctx *cli.Context) {
|
||||
log.Printf("Removing tmp work dir: %s", TmpWorkDir)
|
||||
os.RemoveAll(TmpWorkDir)
|
||||
log.Printf("Finish dumping in file %s", fileName)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ func handleUpdateTask(uuid string, user, repoUser *models.User, reponame string,
|
||||
}
|
||||
}
|
||||
|
||||
func runServ(c *cli.Context) {
|
||||
func runServ(c *cli.Context) error {
|
||||
if c.IsSet("config") {
|
||||
setting.CustomConf = c.String("config")
|
||||
}
|
||||
@@ -138,7 +138,7 @@ func runServ(c *cli.Context) {
|
||||
|
||||
if setting.SSH.Disabled {
|
||||
println("Gogs: SSH has been disabled")
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(c.Args()) < 1 {
|
||||
@@ -149,7 +149,7 @@ func runServ(c *cli.Context) {
|
||||
if len(cmd) == 0 {
|
||||
println("Hi there, You've successfully authenticated, but Gogs does not provide shell access.")
|
||||
println("If this is unexpected, please log in with password and setup Gogs under another user.")
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
verb, args := parseCmd(cmd)
|
||||
@@ -290,4 +290,6 @@ func runServ(c *cli.Context) {
|
||||
fail("Internal error", "UpdatePublicKey: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ var CmdUpdate = cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
func runUpdate(c *cli.Context) {
|
||||
func runUpdate(c *cli.Context) error {
|
||||
if c.IsSet("config") {
|
||||
setting.CustomConf = c.String("config")
|
||||
}
|
||||
@@ -33,7 +33,7 @@ func runUpdate(c *cli.Context) {
|
||||
|
||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||
log.GitLogger.Trace("SSH_ORIGINAL_COMMAND is empty")
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
args := c.Args()
|
||||
@@ -53,4 +53,6 @@ func runUpdate(c *cli.Context) {
|
||||
if err := models.AddUpdateTask(&task); err != nil {
|
||||
log.GitLogger.Fatal(2, "AddUpdateTask: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
28
cmd/web.go
28
cmd/web.go
@@ -78,21 +78,24 @@ func checkVersion() {
|
||||
|
||||
// Check dependency version.
|
||||
checkers := []VerChecker{
|
||||
{"github.com/go-xorm/xorm", func() string { return xorm.Version }, "0.5.2.0304"},
|
||||
{"github.com/go-macaron/binding", binding.Version, "0.2.1"},
|
||||
{"github.com/go-xorm/xorm", func() string { return xorm.Version }, "0.5.5"},
|
||||
{"github.com/go-macaron/binding", binding.Version, "0.3.2"},
|
||||
{"github.com/go-macaron/cache", cache.Version, "0.1.2"},
|
||||
{"github.com/go-macaron/csrf", csrf.Version, "0.1.0"},
|
||||
{"github.com/go-macaron/i18n", i18n.Version, "0.2.0"},
|
||||
{"github.com/go-macaron/i18n", i18n.Version, "0.3.0"},
|
||||
{"github.com/go-macaron/session", session.Version, "0.1.6"},
|
||||
{"github.com/go-macaron/toolbox", toolbox.Version, "0.1.0"},
|
||||
{"gopkg.in/ini.v1", ini.Version, "1.8.4"},
|
||||
{"gopkg.in/macaron.v1", macaron.Version, "1.1.2"},
|
||||
{"github.com/gogits/git-module", git.Version, "0.2.9"},
|
||||
{"gopkg.in/macaron.v1", macaron.Version, "1.1.4"},
|
||||
{"github.com/gogits/git-module", git.Version, "0.3.3"},
|
||||
{"github.com/gogits/go-gogs-client", gogs.Version, "0.7.4"},
|
||||
}
|
||||
for _, c := range checkers {
|
||||
if !version.Compare(c.Version(), c.Expected, ">=") {
|
||||
log.Fatal(4, "Package '%s' version is too old (%s -> %s), did you forget to update?", c.ImportPath, c.Version(), c.Expected)
|
||||
log.Fatal(4, `Dependency outdated!
|
||||
Package '%s' current version (%s) is below requirement (%s),
|
||||
please use following command to update this package and recompile Gogs:
|
||||
go get -u %[1]s`, c.ImportPath, c.Version(), c.Expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,12 +126,16 @@ func newMacaron() *macaron.Macaron {
|
||||
SkipLogging: setting.DisableRouterLog,
|
||||
},
|
||||
))
|
||||
|
||||
funcMap := template.NewFuncMap()
|
||||
m.Use(macaron.Renderer(macaron.RenderOptions{
|
||||
Directory: path.Join(setting.StaticRootPath, "templates"),
|
||||
AppendDirectories: []string{path.Join(setting.CustomPath, "templates")},
|
||||
Funcs: template.NewFuncMap(),
|
||||
Funcs: funcMap,
|
||||
IndentJSON: macaron.Env != macaron.PROD,
|
||||
}))
|
||||
models.InitMailRender(path.Join(setting.StaticRootPath, "templates/mail"),
|
||||
path.Join(setting.CustomPath, "templates/mail"), funcMap)
|
||||
|
||||
localeNames, err := bindata.AssetDir("conf/locale")
|
||||
if err != nil {
|
||||
@@ -175,7 +182,7 @@ func newMacaron() *macaron.Macaron {
|
||||
return m
|
||||
}
|
||||
|
||||
func runWeb(ctx *cli.Context) {
|
||||
func runWeb(ctx *cli.Context) error {
|
||||
if ctx.IsSet("config") {
|
||||
setting.CustomConf = ctx.String("config")
|
||||
}
|
||||
@@ -520,9 +527,10 @@ func runWeb(ctx *cli.Context) {
|
||||
m.Get("/src/*", repo.Home)
|
||||
m.Get("/raw/*", repo.SingleDownload)
|
||||
m.Get("/commits/*", repo.RefCommits)
|
||||
m.Get("/commit/*", repo.Diff)
|
||||
m.Get("/commit/:sha([a-z0-9]{40})$", repo.Diff)
|
||||
m.Get("/forks", repo.Forks)
|
||||
}, context.RepoRef())
|
||||
m.Get("/commit/:sha([a-z0-9]{40})\\.:ext(patch|diff)", repo.RawDiff)
|
||||
|
||||
m.Get("/compare/:before([a-z0-9]{40})\\.\\.\\.:after([a-z0-9]{40})", repo.CompareDiff)
|
||||
}, ignSignIn, context.RepoAssignment(), repo.MustBeNotBare)
|
||||
@@ -584,4 +592,6 @@ func runWeb(ctx *cli.Context) {
|
||||
if err != nil {
|
||||
log.Fatal(4, "Fail to start server: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
48
conf/app.ini
48
conf/app.ini
@@ -12,7 +12,7 @@ RUN_MODE = dev
|
||||
ROOT =
|
||||
SCRIPT_TYPE = bash
|
||||
; Default ANSI charset
|
||||
ANSI_CHARSET =
|
||||
ANSI_CHARSET =
|
||||
; Force every new repository to be private
|
||||
FORCE_PRIVATE = false
|
||||
; Global maximum creation limit of repository per user, -1 means no limit
|
||||
@@ -31,6 +31,8 @@ FEED_MAX_COMMIT_NUM = 5
|
||||
; An invalid color like "none" or "disable" will have the default style
|
||||
; More info: https://developers.google.com/web/updates/2014/11/Support-for-theme-color-in-Chrome-39-for-Android
|
||||
THEME_COLOR_META_TAG = `#ff5343`
|
||||
; Max size of files to be displayed (defaults is 8MiB)
|
||||
MAX_DISPLAY_FILE_SIZE = 8388608
|
||||
|
||||
[ui.admin]
|
||||
; Number of users that are showed in one page
|
||||
@@ -53,12 +55,12 @@ CUSTOM_URL_SCHEMES =
|
||||
PROTOCOL = http
|
||||
DOMAIN = localhost
|
||||
ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
|
||||
HTTP_ADDR =
|
||||
HTTP_ADDR = 0.0.0.0
|
||||
HTTP_PORT = 3000
|
||||
; Local (DMZ) URL for Gogs workers (such as SSH update) accessing web service.
|
||||
; In most cases you do not need to change the default value.
|
||||
; Alter it only if your SSH server node is not the same as HTTP node.
|
||||
LOCAL_ROOT_URL = http://localhost:%(HTTP_PORT)s/
|
||||
LOCAL_ROOT_URL = %(PROTOCOL)s://%(HTTP_ADDR)s:%(HTTP_PORT)s/
|
||||
; Disable SSH feature when not available
|
||||
DISABLE_SSH = false
|
||||
; Whether use builtin SSH server or not.
|
||||
@@ -70,7 +72,7 @@ SSH_PORT = 22
|
||||
; Port number builtin SSH server listens on
|
||||
SSH_LISTEN_PORT = %(SSH_PORT)s
|
||||
; Root path of SSH directory, default is '~/.ssh', but you have to use '/home/git/.ssh'.
|
||||
SSH_ROOT_PATH =
|
||||
SSH_ROOT_PATH =
|
||||
; Directory to create temporary files when test publick key using ssh-keygen,
|
||||
; default is system temporary directory.
|
||||
SSH_KEY_TEST_PATH =
|
||||
@@ -167,24 +169,26 @@ SEND_BUFFER_LEN = 100
|
||||
SUBJECT = %(APP_NAME)s
|
||||
; Mail server
|
||||
; Gmail: smtp.gmail.com:587
|
||||
; QQ: smtp.qq.com:25
|
||||
; QQ: smtp.qq.com:465
|
||||
; Note, if the port ends with "465", SMTPS will be used. Using STARTTLS on port 587 is recommended per RFC 6409. If the server supports STARTTLS it will always be used.
|
||||
HOST =
|
||||
HOST =
|
||||
; Disable HELO operation when hostname are different.
|
||||
DISABLE_HELO =
|
||||
DISABLE_HELO =
|
||||
; Custom hostname for HELO operation, default is from system.
|
||||
HELO_HOSTNAME =
|
||||
HELO_HOSTNAME =
|
||||
; Do not verify the certificate of the server. Only use this for self-signed certificates
|
||||
SKIP_VERIFY =
|
||||
SKIP_VERIFY =
|
||||
; Use client certificate
|
||||
USE_CERTIFICATE = false
|
||||
CERT_FILE = custom/mailer/cert.pem
|
||||
KEY_FILE = custom/mailer/key.pem
|
||||
; Mail from address, RFC 5322. This can be just an email address, or the `"Name" <email@example.com>` format
|
||||
; Mail from address, RFC 5322. This can be just an email address, or the `"Name" <email@example.com>` format
|
||||
FROM =
|
||||
; Mailer user name and password
|
||||
USER =
|
||||
PASSWD =
|
||||
; Use text/html as alternative format of content
|
||||
ENABLE_HTML_ALTERNATIVE = false
|
||||
|
||||
[cache]
|
||||
; Either "memory", "redis", or "memcache", default is "memory"
|
||||
@@ -197,7 +201,7 @@ INTERVAL = 60
|
||||
HOST =
|
||||
|
||||
[session]
|
||||
; Either "memory", "file", "redis" or "mysql", default is "memory"
|
||||
; Either "memory", "file", or "redis", default is "memory"
|
||||
PROVIDER = memory
|
||||
; Provider config options
|
||||
; memory: not have any config yet
|
||||
@@ -318,7 +322,7 @@ SCHEDULE = @every 24h
|
||||
TIMEOUT = 60s
|
||||
; Arguments for command 'git fsck', e.g. "--unreachable --tags"
|
||||
; see more on http://git-scm.com/docs/git-fsck/1.7.5
|
||||
ARGS =
|
||||
ARGS =
|
||||
|
||||
; Check repository statistics
|
||||
[cron.check_repo_stats]
|
||||
@@ -326,10 +330,15 @@ RUN_AT_START = true
|
||||
SCHEDULE = @every 24h
|
||||
|
||||
[git]
|
||||
MAX_GIT_DIFF_LINES = 10000
|
||||
; Max number of lines allowed of a single file in diff view.
|
||||
MAX_GIT_DIFF_LINES = 1000
|
||||
; Max number of characters of a line allowed in diff view.
|
||||
MAX_GIT_DIFF_LINE_CHARACTERS = 500
|
||||
; Max number of files shown in diff view.
|
||||
MAX_GIT_DIFF_FILES = 100
|
||||
; Arguments for command 'git gc', e.g. "--aggressive --auto"
|
||||
; see more on http://git-scm.com/docs/git-gc/1.7.5
|
||||
GC_ARGS =
|
||||
GC_ARGS =
|
||||
|
||||
; Operation timeout in seconds
|
||||
[git.timeout]
|
||||
@@ -338,15 +347,20 @@ MIRROR = 300
|
||||
CLONE = 300
|
||||
PULL = 300
|
||||
|
||||
[api]
|
||||
; Max number of items will response in a page
|
||||
MAX_RESPONSE_ITEMS = 50
|
||||
|
||||
[i18n]
|
||||
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI
|
||||
NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands,Latviešu,Русский,日本語,Español,Português do Brasil,Polski,български,Italiano,Suomalainen
|
||||
LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ
|
||||
NAMES = English,简体中文,繁體中文(香港),繁體中文(台湾),Deutsch,Français,Nederlands,Latviešu,Русский,日本語,Español,Português do Brasil,Polski,български,Italiano,Suomalainen,Türkçe,čeština
|
||||
|
||||
; Used for datetimepicker
|
||||
[i18n.datelang]
|
||||
en-US = en
|
||||
zh-CN = zh
|
||||
zh-HK = zh-TW
|
||||
zh-TW = zh-TW
|
||||
de-DE = de
|
||||
fr-FR = fr
|
||||
nl-NL = nl
|
||||
@@ -359,6 +373,8 @@ pl-PL = pl
|
||||
bg-BG = bg
|
||||
it-IT = it
|
||||
fi-FI = fi
|
||||
tr-TR = tr
|
||||
cs-CZ = cs-CZ
|
||||
|
||||
; Extension mapping to highlight class
|
||||
; e.g. .toml=ini
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
ISC License:
|
||||
Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC")
|
||||
Copyright (c) 1995-2003 by Internet Software Consortium
|
||||
Copyright (c) Year(s), Company or Person's Name
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ Antoine GIRARD <sapk AT sapk DOT fr>
|
||||
Arthur Aslanyan <arthur DOT e DOT aslanyan AT gmail DOT com>
|
||||
Aurelien Darragon <aurelien DOT darragon AT gmail DOT com>
|
||||
Barış Arda Yılmaz <ardayilmazgamer AT gmail DOT com>
|
||||
Camille Baronnet <gogs AT camillebaronnet DOT fr>
|
||||
Christoph Kisfeld <christoph DOT kisfeld AT gmail DOT com>
|
||||
Cysioland
|
||||
Daniel Speichert <daniel AT speichert DOT pl>
|
||||
@@ -21,19 +22,20 @@ David Yzaguirre <dvdyzag AT gmail DOT com>
|
||||
Dmitriy Nogay <me AT catwhocode DOT ga>
|
||||
Enrico Testori hypertesto AT gmail DOT com
|
||||
Ezequiel Gonzalez Rial <gonrial AT gmail DOT com>
|
||||
Gabriel Dugny <gabriel DOT dugny AT gmail DOT com>
|
||||
Gregor Santner <gdev AT live DOT de>
|
||||
Halil Kaya <halil AT halilkaya DOT net>
|
||||
Hamid Feizabadi <hamidfzm AT gmail DOT com>
|
||||
Huimin Wang <wanghm2009 AT hotmail DOT co DOT jp>
|
||||
ilko <kontact-mr.k AT outlook DOT com">
|
||||
Ilya Makarov
|
||||
Robert Nuske <robert DOT nuske AT web DOT de>
|
||||
Robin Hübner <profan AT prfn DOT se>
|
||||
Jamie Mansfield <dev AT jamierocks DOT uk>
|
||||
Jean THOMAS <contact AT tibounise DOT com>
|
||||
Juraj Bubniak <contact AT jbub DOT eu>
|
||||
Lafriks <lafriks AT gmail DOT com>
|
||||
Lauri Ojansivu <x AT xet7 DOT org>
|
||||
Luc Stepniewski <luc AT stepniewski DOT fr>
|
||||
Luca Bozzo <luca AT bozzo DOT it>
|
||||
Luca Kröger <l DOT kroeger01 AT gmail DOT com>
|
||||
Marc Schiller <marc AT schiller DOT im>
|
||||
Marvin Menzerath <github AT marvin-menzerath DOT de>
|
||||
@@ -45,6 +47,9 @@ Muhammad Fawwaz Orabi <mfawwaz93 AT gmail DOT com>
|
||||
Nakao Takamasa <at.mattenn AT gmail DOT com>
|
||||
Natan Albuquerque <natanalbuquerque5 AT gmail DOT com>
|
||||
Odilon Junior <odilon DOT junior93 AT gmail DOT com>
|
||||
Richard Bukovansky <richard DOT bukovansky @ gmail DOT com>
|
||||
Robert Nuske <robert DOT nuske AT web DOT de>
|
||||
Robin Hübner <profan AT prfn DOT se>
|
||||
SeongJae Park <sj38 DOT park AT gmail DOT com>
|
||||
Thomas Fanninger <gogs DOT thomas AT fanninger DOT at>
|
||||
Tilmann Bach <tilmann AT outlook DOT com>
|
||||
@@ -53,3 +58,4 @@ Vladimir Jigulin mogaika AT yandex DOT ru
|
||||
Vladimir Vissoultchev <wqweto AT gmail DOT com>
|
||||
YJSoft <yjsoft AT yjsoft DOT pe DOT kr>
|
||||
Łukasz Jan Niemier <lukasz AT niemier DOT pl>
|
||||
Pablo Saavedra <psaavedra AT igalia DOT com>
|
||||
|
||||
24
conf/locale/locale_bg-BG.ini
Executable file → Normal file
24
conf/locale/locale_bg-BG.ini
Executable file → Normal file
@@ -148,6 +148,8 @@ forget_password=Забравена парола?
|
||||
sign_up_now=Нуждаете се от профил? Регистрирайте се сега.
|
||||
confirmation_mail_sent_prompt=Ново писмо за потвърждение е изпратено до <b>%s</b>. Моля проверете пощенската си кутия в рамките на следващите %d часа, за да завършите процеса на регистрация.
|
||||
active_your_account=Активиране на профил
|
||||
prohibit_login=Login Prohibited
|
||||
prohibit_login_desc=Your account is prohibited to login, please contact site admin.
|
||||
resent_limit_prompt=За съжаление Вие съвсем наскоро изпратихте писмо за активация. Моля изчакайте 3 минути, след което опитайте отново.
|
||||
has_unconfirmed_mail=Здравейте %s, имате непотвърден адрес на ел. поща (<b>%s</b>). Ако не сте получили писмо за потвърждение или имате нужда да се изпрати ново писмо, моля щракнете бутона по-долу.
|
||||
resend_mail=Щракнете тук, за да се изпрати ново писмо за потвърждение
|
||||
@@ -157,6 +159,7 @@ reset_password=Нулиране на паролата
|
||||
invalid_code=За съжаление Вашия код за потвърждение е изтекъл или е невалиден.
|
||||
reset_password_helper=Щракнете тук, за да нулирате паролата си
|
||||
password_too_short=Размерът на паролата не може да бъде по-малък от 6 знака.
|
||||
non_local_account=Non-local accounts cannot change passwords through Gogs.
|
||||
|
||||
[mail]
|
||||
activate_account=Моля активирайте Вашия профил
|
||||
@@ -219,8 +222,7 @@ org_still_own_repo=Тази организация все още притежа
|
||||
target_branch_not_exist=Целевият клон не съществува.
|
||||
|
||||
[user]
|
||||
change_avatar=Сменете Вашия аватар на gravatar.com
|
||||
change_custom_avatar=Сменете Вашия аватар в настройките
|
||||
change_avatar=Change your avatar
|
||||
join_on=Регистриран
|
||||
repositories=Хранилища
|
||||
activity=Публична дейност
|
||||
@@ -350,6 +352,8 @@ readme_helper=Изберете шаблон на readme
|
||||
auto_init=Инициализиране на това хранилище с избраните файлове и шаблон
|
||||
create_repo=Създай хранилище
|
||||
default_branch=Клон по подразбиране
|
||||
mirror_prune=Prune
|
||||
mirror_prune_desc=Remove any remote-tracking references that no longer exist on the remote
|
||||
mirror_interval=Интервал на отразяване (часове)
|
||||
mirror_address=Адрес на огледало
|
||||
mirror_address_desc=Моля включете потребител и парола в адреса ако са нужни.
|
||||
@@ -407,6 +411,7 @@ file_raw=Директен файл
|
||||
file_history=История
|
||||
file_view_raw=Виж директен файл
|
||||
file_permalink=Постоянна връзка
|
||||
file_too_large=This file is too large to be shown
|
||||
|
||||
commits.commits=Ревизии
|
||||
commits.search=Търсене в ревизии
|
||||
@@ -561,6 +566,10 @@ wiki.last_updated=Последна модификация на %s
|
||||
settings=Настройки
|
||||
settings.options=Опции
|
||||
settings.collaboration=Сътрудничество
|
||||
settings.collaboration.admin=Admin
|
||||
settings.collaboration.write=Write
|
||||
settings.collaboration.read=Read
|
||||
settings.collaboration.undefined=Undefined
|
||||
settings.hooks=Уеб-куки
|
||||
settings.githooks=Git куки
|
||||
settings.basic_settings=Основни настройки
|
||||
@@ -575,6 +584,9 @@ settings.external_wiki_url_desc=Посетителите ще бъдат пре
|
||||
settings.issues_desc=Включва вградена система за проследяване на задачи
|
||||
settings.use_external_issue_tracker=Използвай външна система за проследяване на задачи
|
||||
settings.tracker_url_format=Формат на URL адрес на външна система за проследяване на задачи
|
||||
settings.tracker_issue_style=External Issue Tracker Naming Style:
|
||||
settings.tracker_issue_style.numeric=Numeric <span class="ui light grey text">(1234)</span>
|
||||
settings.tracker_issue_style.alphanumeric=Alphanumeric <span class="ui light grey text">(ABC-123, DEFG-234, ...)</span>
|
||||
settings.tracker_url_format_desc=Можете да използвате текстови маркери <code>{user} {repo} {index}</code> за потребителско име, име на хранилище и индекс на задача съответно.
|
||||
settings.pulls_desc=Включва заявки за сливане за да може да се приемат външни доработки
|
||||
settings.danger_zone=Опасна зона
|
||||
@@ -597,9 +609,7 @@ settings.delete=Изтрий това хранилище
|
||||
settings.delete_desc=След като изтриете хранилището, няма връщане назад. Моля, бъдете сигурни.
|
||||
settings.delete_notices_1=- Тази операция <strong>НЕ МОЖЕ</strong> да бъде отменена в последствие.
|
||||
settings.delete_notices_2=- Тази операция ще изтрие всичко от това хранилище, включително Git данни, задачи, коментари и достъпа на сътрудници.
|
||||
settings.delete_notices_fork_1=- Ако това хранилище е публично, всички негови разклонения ще останат независими след изтриването му.
|
||||
settings.delete_notices_fork_2=- Ако това хранилище е частно, всички негови разклонения ще бъдат премахнати по време на изтриването.
|
||||
settings.delete_notices_fork_3=- Ако желаете да запазите всички разклонения след изтриването му, първо направете хранилището публично.
|
||||
settings.delete_notices_fork_1=- All forks will become independent after deletion.
|
||||
settings.deletion_success=Хранилището е изтрито успешно!
|
||||
settings.update_settings_success=Настройките на хранилището са запазени успешно.
|
||||
settings.transfer_owner=Нов притежател
|
||||
@@ -683,6 +693,8 @@ diff.show_unified_view=Обединен изглед
|
||||
diff.stats_desc=променени са <strong>%d файла</strong>, в които са <strong>добавени %d</strong> реда и са <strong>изтрити %d</strong> реда
|
||||
diff.bin=BIN
|
||||
diff.view_file=Целия файл
|
||||
diff.file_suppressed=File diff suppressed because it is too large
|
||||
diff.too_many_files=Some files were not shown because too many files changed in this diff
|
||||
|
||||
release.releases=Версии
|
||||
release.new_release=Нова версия
|
||||
@@ -880,6 +892,7 @@ users.edit_account=Редактирай профил
|
||||
users.max_repo_creation=Макс. брой хранилища
|
||||
users.max_repo_creation_desc=(Задайте -1 за да се използва глобалния лимит)
|
||||
users.is_activated=Този профил е активиран
|
||||
users.prohibit_login=This account is prohibited to login
|
||||
users.is_admin=Този профил има административни права
|
||||
users.allow_git_hook=Този профил има разрешение да създава Git куки
|
||||
users.allow_import_local=Този профил има права за импорт на локални хранилища
|
||||
@@ -910,6 +923,7 @@ auths.enabled=Активно
|
||||
auths.updated=Последна модификация
|
||||
auths.auth_type=Тип на удостоверяване
|
||||
auths.auth_name=Име на удостоверяване
|
||||
auths.security_protocol=Security Protocol
|
||||
auths.domain=Домейн
|
||||
auths.host=Сървър
|
||||
auths.port=Порт
|
||||
|
||||
1112
conf/locale/locale_cs-CZ.ini
Normal file
1112
conf/locale/locale_cs-CZ.ini
Normal file
File diff suppressed because it is too large
Load Diff
36
conf/locale/locale_de-DE.ini
Executable file → Normal file
36
conf/locale/locale_de-DE.ini
Executable file → Normal file
@@ -148,6 +148,8 @@ forget_password=Passwort vergessen?
|
||||
sign_up_now=Benötigen Sie ein Konto? Registrieren Sie sich jetzt.
|
||||
confirmation_mail_sent_prompt=Eine neue Bestätigungs-E-Mail wurde an <b>%s</b> gesendet. Bitte kontrollieren Sie Ihr Postfach innerhalb der nächsten %d Stunden, um die Registrierung abzuschließen.
|
||||
active_your_account=Aktivieren Sie Ihr Konto
|
||||
prohibit_login=Login Prohibited
|
||||
prohibit_login_desc=Your account is prohibited to login, please contact site admin.
|
||||
resent_limit_prompt=Es tut uns leid, aber Sie haben bereits eine Aktivierungs-E-Mail angefordert. Bitte warten Sie 3 Minuten und probieren Sie es dann nochmal.
|
||||
has_unconfirmed_mail=Hallo %s, Sie haben eine unbestätigte E-Mail-Adresse (<b>%s</b>). Wenn Sie keine Bestätigungs-E-Mail erhalten haben oder eine neue benötigen, klicken Sie bitte auf den folgenden Button.
|
||||
resend_mail=Hier klicken, um die Aktivierungs-E-Mail erneut zu versenden
|
||||
@@ -157,6 +159,7 @@ reset_password=Passwort zurücksetzen
|
||||
invalid_code=Es tut uns leid, der Bestätigungscode ist abgelaufen oder ungültig.
|
||||
reset_password_helper=Hier klicken, um das Passwort zurückzusetzen
|
||||
password_too_short=Das Passwort muss mindenstens 6 Zeichen lang sein.
|
||||
non_local_account=Nicht-lokale Konten können Passwörter nicht via Gogs ändern.
|
||||
|
||||
[mail]
|
||||
activate_account=Bitte aktivieren Sie Ihr Konto
|
||||
@@ -219,8 +222,7 @@ org_still_own_repo=Diese Organisation besitzt noch Repositories. Diese müssen z
|
||||
target_branch_not_exist=Ziel-Branch existiert nicht
|
||||
|
||||
[user]
|
||||
change_avatar=Ändern Sie Ihr Profilbild auf gravatar.com
|
||||
change_custom_avatar=Ändern Sie Ihr Profilbild in den Einstellungen
|
||||
change_avatar=Ändern Sie ihr Profilbild
|
||||
join_on=Beigetreten am
|
||||
repositories=Repositories
|
||||
activity=Öffentliche Aktivität
|
||||
@@ -326,7 +328,7 @@ delete_account=Konto löschen
|
||||
delete_prompt=Diese Aktion wird Ihr Konto dauerhaft löschen und kann <strong>NICHT</strong> rückgängig gemacht werden!
|
||||
confirm_delete_account=Löschvorgang bestätigen
|
||||
delete_account_title=Konto löschen
|
||||
delete_account_desc=Sie sind dabei dieses Konto dauerhaft zu löschen, möchten Sie wirklich fortfahren?
|
||||
delete_account_desc=Sie sind dabei dieses Konto dauerhaft zu löschen. Möchten Sie wirklich fortfahren?
|
||||
|
||||
[repo]
|
||||
owner=Besitzer
|
||||
@@ -342,7 +344,7 @@ fork_from=Fork von
|
||||
fork_visiblity_helper=Die Sichtbarkeit von geforkten Repositories ist nicht veränderbar.
|
||||
repo_desc=Beschreibung
|
||||
repo_lang=Sprache
|
||||
repo_lang_helper=.gitignore Dateien auswählen
|
||||
repo_lang_helper=Wählen Sie eine .gitignore-Datei aus
|
||||
license=Lizenz
|
||||
license_helper=Wählen Sie eine Lizenz aus
|
||||
readme=Readme
|
||||
@@ -350,6 +352,8 @@ readme_helper=Readme Vorlage auswählen
|
||||
auto_init=Repository mit ausgewählten Dateien und Vorlagen initialisieren
|
||||
create_repo=Repository erstellen
|
||||
default_branch=Standard-Branch
|
||||
mirror_prune=Entfernen
|
||||
mirror_prune_desc=Entferne alle Verweise auf nicht mehr existierende entfernte Repositories
|
||||
mirror_interval=Mirror-Intervall (in Stunden)
|
||||
mirror_address=Mirror-Adresse
|
||||
mirror_address_desc=Bitte die nötigen Zugangsdaten in die Adresse mit aufnehmen.
|
||||
@@ -407,6 +411,7 @@ file_raw=Originalformat
|
||||
file_history=Verlauf
|
||||
file_view_raw=Ansicht im Originalformat
|
||||
file_permalink=Permalink
|
||||
file_too_large=This file is too large to be shown
|
||||
|
||||
commits.commits=Commits
|
||||
commits.search=Commits durchsuchen
|
||||
@@ -505,11 +510,11 @@ pulls.merged_title_desc=hat %[1]d Commits von <code>%[2]s</code> nach <code>%[3]
|
||||
pulls.tab_conversation=Diskussion
|
||||
pulls.tab_commits=Commits
|
||||
pulls.tab_files=Geänderte Dateien
|
||||
pulls.reopen_to_merge=Bitte diesen Pull-Request wiedereröffnen, um die Merge-Operation auszuführen.
|
||||
pulls.reopen_to_merge=Bitte diesen Pull-Request wieder eröffnen, um die Merge-Operation auszuführen.
|
||||
pulls.merged=Zusammengeführt
|
||||
pulls.has_merged=Dieser Pull-Request wurde erfolgreich zusammengeführt!
|
||||
pulls.data_broken=Die Daten dieses Pull-Requests sind defekt, da Fork-Informationen gelöscht wurden.
|
||||
pulls.is_checking=Die Konfliktprüfung ist in Arbeit. Bitte aktualisieren Sie die Seite in wenigen Momenten.
|
||||
pulls.is_checking=Die Konfliktprüfung läuft noch. Bitte aktualisieren Sie die Seite in wenigen Augenblicken.
|
||||
pulls.can_auto_merge_desc=Dieser Pull-Request kann automatisch zusammengeführt werden.
|
||||
pulls.cannot_auto_merge_desc=Dieser Pull-Request kann nicht automatisch zusammengeführt werden, da es Konflikte gibt.
|
||||
pulls.cannot_auto_merge_helper=Bitte manuell zusammenführen, um die Konflikte zu lösen.
|
||||
@@ -561,6 +566,10 @@ wiki.last_updated=Zuletzt aktualisiert %s
|
||||
settings=Einstellungen
|
||||
settings.options=Optionen
|
||||
settings.collaboration=Zusammenarbeit
|
||||
settings.collaboration.admin=Adminrechte
|
||||
settings.collaboration.write=Schreibrechte
|
||||
settings.collaboration.read=Leserechte
|
||||
settings.collaboration.undefined=Nicht definiert
|
||||
settings.hooks=Webhooks
|
||||
settings.githooks=Git-Hooks
|
||||
settings.basic_settings=Grundeinstellungen
|
||||
@@ -575,6 +584,9 @@ settings.external_wiki_url_desc=Besucher werden auf diese URL umgeleitet, wenn s
|
||||
settings.issues_desc=Eingebautes einfaches Issue-System verwenden
|
||||
settings.use_external_issue_tracker=Externes Issue-System verwenden
|
||||
settings.tracker_url_format=URL-Format des externen Issue-Systems
|
||||
settings.tracker_issue_style=Namenskonvention des externen Issue-Trackers:
|
||||
settings.tracker_issue_style.numeric=Numerisch <span class="ui light grey text">(1234)</span>
|
||||
settings.tracker_issue_style.alphanumeric=Alphanumerisch <span class="ui light grey text">(ABC-123, DEFG-234, ...)</span>
|
||||
settings.tracker_url_format_desc=Sie können die Platzhalter <code>{user} {repo} {index}</code> für den Benutzernamen, den Namen des Repositories und die Issue-Nummer verwenden.
|
||||
settings.pulls_desc=Pull-Requests aktivieren, um öffentliche Mitwirkung zu ermöglichen
|
||||
settings.danger_zone=Gefahrenzone
|
||||
@@ -597,9 +609,7 @@ settings.delete=Dieses Repository löschen
|
||||
settings.delete_desc=Wenn dieses Repository gelöscht wurde, gibt es keinen Weg zurück. Bitte seien Sie vorsichtig.
|
||||
settings.delete_notices_1=- Diese Operation kann <strong>NICHT</strong> rückgängig gemacht werden.
|
||||
settings.delete_notices_2=- Die Operation wird alles, was mit diesem Git-Repository verbunden ist, dauerhaft löschen, inklusive der Daten, Issues, Kommentare und Zugriffsrechte von Mitarbeitern.
|
||||
settings.delete_notices_fork_1=- Wenn dies ein öffentliches Repository ist, werden nach dem Löschen alle Forks unabhängig.
|
||||
settings.delete_notices_fork_2=- Wenn dies ein privates Repository ist, werden gleichzeitig alle Forks entfernt.
|
||||
settings.delete_notices_fork_3=- Wenn alle Forks erhalten bleiben sollen, dann muss zuerst die Sichtbarkeit dieses Repositories auf öffentlich gesetzt werden.
|
||||
settings.delete_notices_fork_1=- Nach dem Löschen werden alle Forks unabhängig.
|
||||
settings.deletion_success=Repository wurde erfolgreich gelöscht!
|
||||
settings.update_settings_success=Repository-Optionen aktualisiert.
|
||||
settings.transfer_owner=Neuer Besitzer
|
||||
@@ -683,6 +693,8 @@ diff.show_unified_view=Gesamtansicht
|
||||
diff.stats_desc=<strong> %d geänderte Dateien</strong> mit <strong>%d neuen</strong> und <strong>%d gelöschten</strong> Zeilen
|
||||
diff.bin=BIN
|
||||
diff.view_file=Datei anzeigen
|
||||
diff.file_suppressed=File diff suppressed because it is too large
|
||||
diff.too_many_files=Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.
|
||||
|
||||
release.releases=Releases
|
||||
release.new_release=Neues Release
|
||||
@@ -880,6 +892,7 @@ users.edit_account=Konto bearbeiten
|
||||
users.max_repo_creation=Maximale Anzahl erstellbarer Repositories
|
||||
users.max_repo_creation_desc=(Auf -1 setzen, um das globale Standardlimit zu verwenden)
|
||||
users.is_activated=Dieses Konto ist aktiviert
|
||||
users.prohibit_login=This account is prohibited to login
|
||||
users.is_admin=Dieses Konto hat Administratorrechte
|
||||
users.allow_git_hook=Dieses Konto ist berechtigt Git-Hooks zu erstellen
|
||||
users.allow_import_local=Dieses Konto ist berechtigt, lokale Repositories zu importieren
|
||||
@@ -910,6 +923,7 @@ auths.enabled=Aktiviert
|
||||
auths.updated=Aktualisiert
|
||||
auths.auth_type=Authentifizierungstyp
|
||||
auths.auth_name=Authentifizierungsname
|
||||
auths.security_protocol=Sicherheitsprotokoll
|
||||
auths.domain=Domain
|
||||
auths.host=Host
|
||||
auths.port=Port
|
||||
@@ -938,7 +952,7 @@ auths.pam_service_name=PAM Dienstname
|
||||
auths.enable_auto_register=Automatische Registrierung aktivieren
|
||||
auths.tips=Tipps
|
||||
auths.edit=Authentifizierungseinstellungen bearbeiten
|
||||
auths.activated=Diese Authentifizierung ist aktiviert
|
||||
auths.activated=Diese Authentifizierung ist aktiv
|
||||
auths.new_success=Neue Authentifizierung '%s' wurde erfolgreich hinzugefügt.
|
||||
auths.update_success=Die Authentifizierungseinstellungen wurden erfolgreich aktualisiert.
|
||||
auths.update=Authentifizierungseinstellungen aktualisieren
|
||||
@@ -946,7 +960,7 @@ auths.delete=Diese Authentifizierung löschen
|
||||
auths.delete_auth_title=Authentifizierung löschen
|
||||
auths.delete_auth_desc=Diese Authentifizierung wird gelöscht. Möchten Sie fortfahren?
|
||||
auths.still_in_used=Diese Authentifizierung wird noch von einigen Benutzern verwendet. Bitte löschen Sie diese Benutzer oder ändern Sie deren Anmeldetyp.
|
||||
auths.deletion_success=Authentifizierung wurde erfolgreich entfernt!
|
||||
auths.deletion_success=Authentifizierung wurde erfolgreich gelöscht!
|
||||
|
||||
config.server_config=Serverkonfiguration
|
||||
config.app_name=Anwendungsname
|
||||
|
||||
@@ -148,6 +148,8 @@ forget_password = Forgot password?
|
||||
sign_up_now = Need an account? Sign up now.
|
||||
confirmation_mail_sent_prompt = A new confirmation email has been sent to <b>%s</b>, please check your inbox within the next %d hours to complete the registration process.
|
||||
active_your_account = Activate Your Account
|
||||
prohibit_login = Login Prohibited
|
||||
prohibit_login_desc = Your account is prohibited to login, please contact site admin.
|
||||
resent_limit_prompt = Sorry, you already requested an activation email recently. Please wait 3 minutes then try again.
|
||||
has_unconfirmed_mail = Hi %s, you have an unconfirmed email address (<b>%s</b>). If you haven't received a confirmation email or need to resend a new one, please click on the button below.
|
||||
resend_mail = Click here to resend your activation email
|
||||
@@ -220,8 +222,7 @@ org_still_own_repo = This organization still has ownership of repositories, you
|
||||
target_branch_not_exist = Target branch does not exist.
|
||||
|
||||
[user]
|
||||
change_avatar = Change your avatar at gravatar.com
|
||||
change_custom_avatar = Change your avatar in settings
|
||||
change_avatar = Change your avatar
|
||||
join_on = Joined on
|
||||
repositories = Repositories
|
||||
activity = Public Activity
|
||||
@@ -351,6 +352,8 @@ readme_helper = Select a readme template
|
||||
auto_init = Initialize this repository with selected files and template
|
||||
create_repo = Create Repository
|
||||
default_branch = Default Branch
|
||||
mirror_prune = Prune
|
||||
mirror_prune_desc = Remove any remote-tracking references that no longer exist on the remote
|
||||
mirror_interval = Mirror Interval (hour)
|
||||
mirror_address = Mirror Address
|
||||
mirror_address_desc = Please include necessary user credentials in the address.
|
||||
@@ -408,6 +411,7 @@ file_raw = Raw
|
||||
file_history = History
|
||||
file_view_raw = View Raw
|
||||
file_permalink = Permalink
|
||||
file_too_large = This file is too large to be shown
|
||||
|
||||
commits.commits = Commits
|
||||
commits.search = Search commits
|
||||
@@ -562,6 +566,10 @@ wiki.last_updated = Last updated %s
|
||||
settings = Settings
|
||||
settings.options = Options
|
||||
settings.collaboration = Collaboration
|
||||
settings.collaboration.admin = Admin
|
||||
settings.collaboration.write = Write
|
||||
settings.collaboration.read = Read
|
||||
settings.collaboration.undefined = Undefined
|
||||
settings.hooks = Webhooks
|
||||
settings.githooks = Git Hooks
|
||||
settings.basic_settings = Basic Settings
|
||||
@@ -576,6 +584,9 @@ settings.external_wiki_url_desc = Visitors will be redirected to URL when they c
|
||||
settings.issues_desc = Enable builtin lightweight issue tracker
|
||||
settings.use_external_issue_tracker = Use external issue tracker
|
||||
settings.tracker_url_format = External Issue Tracker URL Format
|
||||
settings.tracker_issue_style = External Issue Tracker Naming Style:
|
||||
settings.tracker_issue_style.numeric = Numeric <span class="ui light grey text">(1234)</span>
|
||||
settings.tracker_issue_style.alphanumeric = Alphanumeric <span class="ui light grey text">(ABC-123, DEFG-234, ...)</span>
|
||||
settings.tracker_url_format_desc = You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
|
||||
settings.pulls_desc = Enable pull requests to accept public contributions
|
||||
settings.danger_zone = Danger Zone
|
||||
@@ -598,9 +609,7 @@ settings.delete = Delete This Repository
|
||||
settings.delete_desc = Once you delete a repository, there is no going back. Please be certain.
|
||||
settings.delete_notices_1 = - This operation <strong>CANNOT</strong> be undone.
|
||||
settings.delete_notices_2 = - This operation will permanently delete the everything of this repository, including Git data, issues, comments and accesses of collaborators.
|
||||
settings.delete_notices_fork_1 = - If this repository is public, all forks will become independent after deletion.
|
||||
settings.delete_notices_fork_2 = - If this repository is private, all forks will be removed at the same time.
|
||||
settings.delete_notices_fork_3 = - If you want to keep all forks after deletion, please change visibility of this repository to public first.
|
||||
settings.delete_notices_fork_1 = - All forks will become independent after deletion.
|
||||
settings.deletion_success = Repository has been deleted successfully!
|
||||
settings.update_settings_success = Repository options has been updated successfully.
|
||||
settings.transfer_owner = New Owner
|
||||
@@ -684,6 +693,8 @@ diff.show_unified_view = Unified View
|
||||
diff.stats_desc = <strong> %d changed files</strong> with <strong>%d additions</strong> and <strong>%d deletions</strong>
|
||||
diff.bin = BIN
|
||||
diff.view_file = View File
|
||||
diff.file_suppressed = File diff suppressed because it is too large
|
||||
diff.too_many_files = Some files were not shown because too many files changed in this diff
|
||||
|
||||
release.releases = Releases
|
||||
release.new_release = New Release
|
||||
@@ -881,6 +892,7 @@ users.edit_account = Edit Account
|
||||
users.max_repo_creation = Maximum Repository Creation Limit
|
||||
users.max_repo_creation_desc = (Set -1 to use global default limit)
|
||||
users.is_activated = This account is activated
|
||||
users.prohibit_login = This account is prohibited to login
|
||||
users.is_admin = This account has administrator permissions
|
||||
users.allow_git_hook = This account has permissions to create Git hooks
|
||||
users.allow_import_local = This account has permissions to import local repositories
|
||||
@@ -911,6 +923,7 @@ auths.enabled = Enabled
|
||||
auths.updated = Updated
|
||||
auths.auth_type = Authentication Type
|
||||
auths.auth_name = Authentication Name
|
||||
auths.security_protocol = Security Protocol
|
||||
auths.domain = Domain
|
||||
auths.host = Host
|
||||
auths.port = Port
|
||||
@@ -939,7 +952,7 @@ auths.pam_service_name = PAM Service Name
|
||||
auths.enable_auto_register = Enable Auto Registration
|
||||
auths.tips = Tips
|
||||
auths.edit = Edit Authentication Setting
|
||||
auths.activated = This authentication is activate
|
||||
auths.activated = This authentication is activated
|
||||
auths.new_success = New authentication '%s' has been added successfully.
|
||||
auths.update_success = Authentication setting has been updated successfully.
|
||||
auths.update = Update Authentication Setting
|
||||
|
||||
40
conf/locale/locale_es-ES.ini
Executable file → Normal file
40
conf/locale/locale_es-ES.ini
Executable file → Normal file
@@ -6,7 +6,7 @@ explore=Explorar
|
||||
help=Ayuda
|
||||
sign_in=Iniciar sesión
|
||||
sign_out=Cerrar sesión
|
||||
sign_up=Suscripción
|
||||
sign_up=Registro
|
||||
register=Registro
|
||||
website=Página web
|
||||
version=Versión
|
||||
@@ -47,7 +47,7 @@ cancel=Cancelar
|
||||
[install]
|
||||
install=Instalación
|
||||
title=Pasos de la instalación por primera vez
|
||||
docker_helper=Si está ejecutando Gogs usando Docker, por favor lea <a target="_blank" href="%s"> estas pautas</a> antes de cambiar nada en esta página!
|
||||
docker_helper=Si está ejecutando Gogs usando Docker, ¡por favor lea <a target="_blank" href="%s"> estas pautas</a> antes de cambiar nada en esta página!
|
||||
requite_db_desc=Gogs requiere una base de datos MySQL, PostgreSQL, SQLite3 o TiDB.
|
||||
db_title=Configuración de base de datos
|
||||
db_type=Tipo de base de datos
|
||||
@@ -65,7 +65,7 @@ no_admin_and_disable_registration=No puede deshabilitar el registro sin crear un
|
||||
err_empty_admin_password=La contraseña de administrador no puede estar vacía.
|
||||
|
||||
general_title=Configuración General de Gogs
|
||||
app_name=Nombre de la Aplicación
|
||||
app_name=Nombre de la aplicación
|
||||
app_name_helper=Pon aquí el nombre de tu organización, ¡alto y claro!
|
||||
repo_path=Ruta del repositorio de Raiz (Root)
|
||||
repo_path_helper=Todos los repositorios remotos de Git se guardarán en este directorio.
|
||||
@@ -137,7 +137,7 @@ users=Usuarios
|
||||
search=Buscar
|
||||
|
||||
[auth]
|
||||
create_new_account=Crear una Nueva Cuenta
|
||||
create_new_account=Crear una nueva cuenta
|
||||
register_hepler_msg=¿Ya tienes una cuenta? ¡Inicia sesión!
|
||||
social_register_hepler_msg=¿Ya tienes una cuenta? ¡Enlázala!
|
||||
disable_register_prompt=Lo sentimos, el registro está deshabilitado. Por favor, contacta con el administrador del sitio.
|
||||
@@ -148,6 +148,8 @@ forget_password=¿Has olvidado tu contraseña?
|
||||
sign_up_now=¿Necesitas una cuenta? Regístrate ahora.
|
||||
confirmation_mail_sent_prompt=Un nuevo correo de confirmación se ha enviado a <b>%s</b>. Por favor, comprueba tu bandeja de entrada en las siguientes %d horas para completar el proceso de registro.
|
||||
active_your_account=Activa tu cuenta
|
||||
prohibit_login=Login Prohibited
|
||||
prohibit_login_desc=Your account is prohibited to login, please contact site admin.
|
||||
resent_limit_prompt=Lo sentimos, estás solicitando el reenvío del mail de activación con demasiada frecuencia. Por favor, espera 3 minutos.
|
||||
has_unconfirmed_mail=Hola %s, tu correo electrónico (<b>%s</b>) no está confirmado. Si no has recibido un correo de confirmación o necesitas que lo enviemos de nuevo, por favor, haz click en el siguiente botón.
|
||||
resend_mail=Haz click aquí para reenviar tu correo electrónico de activación
|
||||
@@ -157,6 +159,7 @@ reset_password=Restablecer su contraseña
|
||||
invalid_code=Lo sentimos, su código de confirmación ha expirado o no es valido.
|
||||
reset_password_helper=Haga Clic aquí para restablecer su contraseña
|
||||
password_too_short=La longitud de la contraseña no puede ser menor a 6.
|
||||
non_local_account=Cuentas que no son locales no pueden cambiar las contraseñas a través de Gogs.
|
||||
|
||||
[mail]
|
||||
activate_account=Por favor, active su cuenta
|
||||
@@ -219,9 +222,8 @@ org_still_own_repo=Esta organización es dueña de uno o más repositorios, tien
|
||||
target_branch_not_exist=La rama de destino no existe
|
||||
|
||||
[user]
|
||||
change_avatar=Cambia tu avatar en gravatar.com
|
||||
change_custom_avatar=Cambia tu avatar en la configuración
|
||||
join_on=Registrado en
|
||||
change_avatar=Cambiar tu avatar
|
||||
join_on=Registrado el
|
||||
repositories=Repositorios
|
||||
activity=Actividad pública
|
||||
followers=Seguidores
|
||||
@@ -341,7 +343,7 @@ fork_repo=Hacer Fork del repositorio
|
||||
fork_from=Crear un Fork desde
|
||||
fork_visiblity_helper=No es posible cambiar la visibilidad de un Fork
|
||||
repo_desc=Descripción
|
||||
repo_lang=Lenguaje
|
||||
repo_lang=Idioma
|
||||
repo_lang_helper=Seleccione archivo .gitignore
|
||||
license=Licencia
|
||||
license_helper=Selecciona un fichero de licencia
|
||||
@@ -350,6 +352,8 @@ readme_helper=Seleccione una plantilla de archivo readme
|
||||
auto_init=Inicializar los archivos seleccionados y plantillas de este repositorio
|
||||
create_repo=Crear repositorio
|
||||
default_branch=Rama por defecto
|
||||
mirror_prune=Prune
|
||||
mirror_prune_desc=Remove any remote-tracking references that no longer exist on the remote
|
||||
mirror_interval=Intervalo de la réplica (en horas)
|
||||
mirror_address=Dirección de la réplica
|
||||
mirror_address_desc=Por favor, incluya las credenciales de usuario necesarias en la dirección.
|
||||
@@ -379,12 +383,12 @@ copy_link_success=¡Copiado!
|
||||
copy_link_error=Presione ⌘ + C o Ctrl-C para copiar
|
||||
copied=Copiado correctamente
|
||||
unwatch=Dejar de vigilar
|
||||
watch=Vigilar
|
||||
watch=Seguir
|
||||
unstar=Eliminar destacado
|
||||
star=Destacar
|
||||
fork=Fork
|
||||
|
||||
no_desc=Sin Descripción
|
||||
no_desc=Sin descripción
|
||||
quick_guide=Guía Rápida
|
||||
clone_this_repo=Clonar este repositorio
|
||||
create_new_repo_command=Crear un nuevo repositorio desde línea de comandos
|
||||
@@ -407,6 +411,7 @@ file_raw=Raw
|
||||
file_history=Histórico
|
||||
file_view_raw=Ver Raw
|
||||
file_permalink=Permalink
|
||||
file_too_large=This file is too large to be shown
|
||||
|
||||
commits.commits=Commits
|
||||
commits.search=Buscar Commits
|
||||
@@ -561,6 +566,10 @@ wiki.last_updated=Última actualización %s
|
||||
settings=Configuración
|
||||
settings.options=Opciones
|
||||
settings.collaboration=Colaboración
|
||||
settings.collaboration.admin=Administrador
|
||||
settings.collaboration.write=Escritura
|
||||
settings.collaboration.read=Lectura
|
||||
settings.collaboration.undefined=Indefinido
|
||||
settings.hooks=Webhooks
|
||||
settings.githooks=Git Hooks
|
||||
settings.basic_settings=Configuración Básica
|
||||
@@ -575,6 +584,9 @@ settings.external_wiki_url_desc=Los visitantes serán redireccionados a la URL c
|
||||
settings.issues_desc=Habilitar tracker ligero de incidencias
|
||||
settings.use_external_issue_tracker=Usar tracker externo de incidencias
|
||||
settings.tracker_url_format=Formato URL del tracker de incidencias externo
|
||||
settings.tracker_issue_style=Estilo de etiquetado del tracker externo de incidencias:
|
||||
settings.tracker_issue_style.numeric=Numérico <span class="ui light grey text">(1234)</span>
|
||||
settings.tracker_issue_style.alphanumeric=Alfanumérico <span class="ui light grey text">(ABC-123, DEFG-234, ...)</span>
|
||||
settings.tracker_url_format_desc=Puedes usar las plantillas <code>{user} {repo} {index}</code> para el nombre de usuario, nombre del repositorio e índice de la incidencia.
|
||||
settings.pulls_desc=Habilitar Pull Requests para aceptar contribuciones públicas
|
||||
settings.danger_zone=Zona de Peligro
|
||||
@@ -597,9 +609,7 @@ settings.delete=Eliminar este repositorio
|
||||
settings.delete_desc=Una vez has eliminado un repositorio, no hay vuelta atrás. Por favor, asegúrate de que es lo que quieres.
|
||||
settings.delete_notices_1=- Esta operación <strong>NO PUEDE</strong> revertirse.
|
||||
settings.delete_notices_2=- Esta operación eliminará de manera permanente todo el contenido de este repositorio, incluyendo los datos de git, las incidencias, los comentarios y los permisos de acceso de los colaboradores.
|
||||
settings.delete_notices_fork_1=- Si este repositorio es público, todos los forks se convertirán en repositorios independientes tras el borrado.
|
||||
settings.delete_notices_fork_2=- Si este repositorio es privado, todos los forks serán eliminados simultáneamente.
|
||||
settings.delete_notices_fork_3=- Si desea mantener los forks tras el borrado, por favor convierta este repositorio en público antes de proceder.
|
||||
settings.delete_notices_fork_1=- Todos los forks se convertirán en independientes tras el borrado.
|
||||
settings.deletion_success=¡El respositorio ha sido eliminado satisfactoriamente!
|
||||
settings.update_settings_success=Las opciones del repositorio se han actualizado correctamente.
|
||||
settings.transfer_owner=Nuevo Propietario
|
||||
@@ -683,6 +693,8 @@ diff.show_unified_view=Unificar vista
|
||||
diff.stats_desc=Se han <strong>modificado %d ficheros</strong> con <strong>%d adiciones</strong> y <strong>%d borrados</strong>
|
||||
diff.bin=BIN
|
||||
diff.view_file=Ver fichero
|
||||
diff.file_suppressed=File diff suppressed because it is too large
|
||||
diff.too_many_files=Some files were not shown because too many files changed in this diff
|
||||
|
||||
release.releases=Releases
|
||||
release.new_release=Nueva Release
|
||||
@@ -880,6 +892,7 @@ users.edit_account=Editar Cuenta
|
||||
users.max_repo_creation=Límite máximo de repositorios
|
||||
users.max_repo_creation_desc=(Configura a -1 para usar el límite global por defecto)
|
||||
users.is_activated=Esta cuenta está activada
|
||||
users.prohibit_login=This account is prohibited to login
|
||||
users.is_admin=Esta cuenta tiene permisos de administrador
|
||||
users.allow_git_hook=Esta cuenta tiene permisos para crear hooks de Git
|
||||
users.allow_import_local=Esta cuenta dispone de permisos para importar repositorios locales
|
||||
@@ -910,6 +923,7 @@ auths.enabled=Activo
|
||||
auths.updated=Actualizado
|
||||
auths.auth_type=Tipo de autenticación
|
||||
auths.auth_name=Nombre de autenticación
|
||||
auths.security_protocol=Protocolo de seguridad
|
||||
auths.domain=Dominio
|
||||
auths.host=Host
|
||||
auths.port=Puerto
|
||||
|
||||
24
conf/locale/locale_fi-FI.ini
Executable file → Normal file
24
conf/locale/locale_fi-FI.ini
Executable file → Normal file
@@ -148,6 +148,8 @@ forget_password=Unohtuiko salasana?
|
||||
sign_up_now=Tarvitsetko tilin? Rekisteröidy nyt.
|
||||
confirmation_mail_sent_prompt=Uusi varmistus sähköposti on lähetetty osoitteeseen <b>%s</b>, ole hyvä ja tarkista saapuneet seuraavan %d tunnin sisällä saadaksesi rekisteröintiprosessin valmiiksi.
|
||||
active_your_account=Aktivoi tilisi
|
||||
prohibit_login=Login Prohibited
|
||||
prohibit_login_desc=Your account is prohibited to login, please contact site admin.
|
||||
resent_limit_prompt=Sori, olet jo tilannut aktivointi sähköpostin lähiaikoina. Ole hyvä ja odota 3 minuuttia ja yritä sitten uudelleen.
|
||||
has_unconfirmed_mail=Hei %s, sinulla on varmistamaton sähköposti osoite (<b>%s</b>). Jos et ole saanut varmistus sähköpostia tai tarvitset uudelleenlähetyksen, ole hyvä ja klikkaa allaolevaa painiketta.
|
||||
resend_mail=Klikkaa tästä uudelleenlähettääksesi aktivointi sähköpostisi
|
||||
@@ -157,6 +159,7 @@ reset_password=Nollaa salasanasi
|
||||
invalid_code=Sori, varmistuskoodisi on vanhentunut tai väärä.
|
||||
reset_password_helper=Klikkaa tästä nollataksesi salasanasi
|
||||
password_too_short=Salasanan pituus ei voi olla vähemmän kuin 6 merkkiä.
|
||||
non_local_account=Non-local accounts cannot change passwords through Gogs.
|
||||
|
||||
[mail]
|
||||
activate_account=Ole hyvä ja aktivoi tilisi
|
||||
@@ -219,8 +222,7 @@ org_still_own_repo=Tällä organisaatiolla on yhä omistajuus repoon, sinun täy
|
||||
target_branch_not_exist=Kohde branchia ei ole olemassa.
|
||||
|
||||
[user]
|
||||
change_avatar=Vaihda avatarisi osoitteeessa gravatar.com
|
||||
change_custom_avatar=Vaihda avatar asetuksissa
|
||||
change_avatar=Change your avatar
|
||||
join_on=Liitytty
|
||||
repositories=Repot
|
||||
activity=Julkinen toiminta
|
||||
@@ -350,6 +352,8 @@ readme_helper=Valitse Lueminut-malli
|
||||
auto_init=Alusta tämä repo valituilla tiedostoilla ja mallilla
|
||||
create_repo=Luo repo
|
||||
default_branch=Oletus branch
|
||||
mirror_prune=Prune
|
||||
mirror_prune_desc=Remove any remote-tracking references that no longer exist on the remote
|
||||
mirror_interval=Peili aikaväli (tuntia)
|
||||
mirror_address=Peili osoite
|
||||
mirror_address_desc=Ole hyvä ja liitä osoitteeseen tarvittavat käyttäjätunnukset.
|
||||
@@ -407,6 +411,7 @@ file_raw=Raaka
|
||||
file_history=Historia
|
||||
file_view_raw=Näytä raaka
|
||||
file_permalink=Pysyvä linkki
|
||||
file_too_large=This file is too large to be shown
|
||||
|
||||
commits.commits=Commitit
|
||||
commits.search=Etsi commiteista
|
||||
@@ -561,6 +566,10 @@ wiki.last_updated=Viimeksi päivitetty: %s
|
||||
settings=Asetukset
|
||||
settings.options=Valinnaiset
|
||||
settings.collaboration=Yhteistyö
|
||||
settings.collaboration.admin=Admin
|
||||
settings.collaboration.write=Write
|
||||
settings.collaboration.read=Read
|
||||
settings.collaboration.undefined=Undefined
|
||||
settings.hooks=Webkoukut
|
||||
settings.githooks=Git koukut
|
||||
settings.basic_settings=Perusasetukset
|
||||
@@ -575,6 +584,9 @@ settings.external_wiki_url_desc=Vierailijat uudelleenohjataan URL-osoitteeseen k
|
||||
settings.issues_desc=Ota käyttöön sisäänrakennettu kevyt vikaseuranta
|
||||
settings.use_external_issue_tracker=Käytä ulkoista vikaseurantaa
|
||||
settings.tracker_url_format=Ulkoisen vikaseurannan URL muoto
|
||||
settings.tracker_issue_style=External Issue Tracker Naming Style:
|
||||
settings.tracker_issue_style.numeric=Numeric <span class="ui light grey text">(1234)</span>
|
||||
settings.tracker_issue_style.alphanumeric=Alphanumeric <span class="ui light grey text">(ABC-123, DEFG-234, ...)</span>
|
||||
settings.tracker_url_format_desc=Voit käyttää paikkamerkkiä <code>{user} {repo} {index}</code> käyttäjänimelle, reponimelle ja vikanumerolle.
|
||||
settings.pulls_desc=Ota käyttöön pull-pyynnöt salliaksesi julkiset koodilahjoitukset
|
||||
settings.danger_zone=Vaaravyöhyke
|
||||
@@ -597,9 +609,7 @@ settings.delete=Poista tämä repo
|
||||
settings.delete_desc=Huomio, kun kerran poistat repon, niin ei ole paluuta. Varmista että haluat todella tehdä tämän.
|
||||
settings.delete_notices_1=- Tätä toimintoa <strong>EI VOI</strong> peruuttaa myöhemmin.
|
||||
settings.delete_notices_2=- Tämä toiminto poistaa pysyvästi kaikki tästä reposta, mukaanlukien Git tiedot, ongelmat, kommentit ja yhteistyökumppanien pääsyoikeudet.
|
||||
settings.delete_notices_fork_1=- Jos tämä repo on julkinen, kaikki forkit tulevat itsenäiseksi poiston jälkeen.
|
||||
settings.delete_notices_fork_2=- Jos tämä repo on yksityinen, kaikki forkit poistetaan samalla.
|
||||
settings.delete_notices_fork_3=- Jos haluat pitää kaikki forkit poistamisen jälkeen, ole hyvä ja muuta tämän repon näkyvyys julkiseksi ensin.
|
||||
settings.delete_notices_fork_1=- All forks will become independent after deletion.
|
||||
settings.deletion_success=Repo on poistettu onnistuneesti!
|
||||
settings.update_settings_success=Repom asetukset on päivitetty onnistuneesti.
|
||||
settings.transfer_owner=Uusi omistaja
|
||||
@@ -683,6 +693,8 @@ diff.show_unified_view=Yhdistetty näkymä
|
||||
diff.stats_desc=<strong>%d muutettua tiedostoa</strong> jossa <strong>%d lisäystä</strong> ja <strong>%d poistoa</strong>
|
||||
diff.bin=BIN
|
||||
diff.view_file=Näytä tiedosto
|
||||
diff.file_suppressed=File diff suppressed because it is too large
|
||||
diff.too_many_files=Some files were not shown because too many files changed in this diff
|
||||
|
||||
release.releases=Julkaisut
|
||||
release.new_release=Uusi julkaisu
|
||||
@@ -880,6 +892,7 @@ users.edit_account=Muokkaa tiliä
|
||||
users.max_repo_creation=Maksimi repojen määrä jonka voi luoda
|
||||
users.max_repo_creation_desc=(Aseta -1 käyttääksesi globaalia oletusrajaa)
|
||||
users.is_activated=Tämä tili on aktivoitu
|
||||
users.prohibit_login=This account is prohibited to login
|
||||
users.is_admin=Tällä tilillä on ylläpito-oikeudet
|
||||
users.allow_git_hook=Tällä tilillä on oikeudet luoda Git koukkuja
|
||||
users.allow_import_local=Tällä tilillä on oikeudet tuoda paikallisia repoja
|
||||
@@ -910,6 +923,7 @@ auths.enabled=Käytössä
|
||||
auths.updated=Päivitetty
|
||||
auths.auth_type=Todennustyyppi
|
||||
auths.auth_name=Todennusnimi
|
||||
auths.security_protocol=Security Protocol
|
||||
auths.domain=Verkkotunnus
|
||||
auths.host=Isäntä
|
||||
auths.port=Portti
|
||||
|
||||
80
conf/locale/locale_fr-FR.ini
Executable file → Normal file
80
conf/locale/locale_fr-FR.ini
Executable file → Normal file
@@ -57,7 +57,7 @@ password=Mot de passe
|
||||
db_name=Nom de base de données
|
||||
db_helper=Veuillez utiliser le moteur INNODB avec le jeu de caractères utf8_general_ci pour MySQL.
|
||||
ssl_mode=Mode SSL
|
||||
path=Chemin
|
||||
path=Emplacement
|
||||
sqlite_helper=Le chemin du fichier de base de données SQLite3 ou TiDB. <br>Utilisez un chemin absolu lorsque vous démarrez en tant que service.
|
||||
err_empty_db_path=Le chemin de la base de données SQLite3 ou TiDB ne peut être vide.
|
||||
err_invalid_tidb_name=Le nom de la base de données TiDB ne peut contenir les caractères "." ou "-".
|
||||
@@ -83,7 +83,7 @@ log_root_path=Chemin des fichiers log
|
||||
log_root_path_helper=Répertoire d'écriture des fichiers de log.
|
||||
|
||||
optional_title=Paramètres facultatifs
|
||||
email_title=Paramètres du Service de Messagerie
|
||||
email_title=Paramètres du service de messagerie
|
||||
smtp_host=Hôte SMTP
|
||||
smtp_from=Provenant de
|
||||
smtp_from_helper=Adresse de l'expéditeur, RFC 5322. Soit une adresse courriel simple, soit au format "Nom" <email@example.com>.
|
||||
@@ -100,7 +100,7 @@ disable_registration=Désactiver le formulaire d'inscription
|
||||
disable_registration_popup=Désactiver le formulaire d'inscription, seuls les administrateurs peuvent créer des comptes.
|
||||
enable_captcha=Activez le Captcha
|
||||
enable_captcha_popup=Demande la validation Captcha pour l'auto-enregistrement de l'utilisateur.
|
||||
require_sign_in_view=Demander une connexion pour afficher des pages
|
||||
require_sign_in_view=Exiger l'identification pour afficher les pages
|
||||
require_sign_in_view_popup=Seules les personnes connectées peuvent voir les pages. Les visiteurs anonymes ne pourront voir que les pages de connexion/enregistrement.
|
||||
admin_setting_desc=Vous n'avez pas besoin de créer un compte administrateur. L'utilisateur ayant l'ID = 1 aura automatiquement accès à l'administration.
|
||||
admin_title=Paramètres du compte administrateur
|
||||
@@ -120,13 +120,13 @@ install_success=Bienvenue ! Nous sommes heureux que vous ayez choisi Gogs, amuse
|
||||
invalid_log_root_path=Le chemin principal des fichiers logs est invalide: %v
|
||||
|
||||
[home]
|
||||
uname_holder=Nom d'Utilisateur ou E-mail
|
||||
uname_holder=Nom d'utilisateur ou e-mail
|
||||
password_holder=Mot de passe
|
||||
switch_dashboard_context=Basculer le Contexte du Tableau de Bord
|
||||
my_repos=Mes dépôts
|
||||
collaborative_repos=Dépôts collaboratifs
|
||||
my_orgs=Mes Organisations
|
||||
my_mirrors=Mes Miroirs
|
||||
my_orgs=Mes organisations
|
||||
my_mirrors=Mes miroirs
|
||||
view_home=Voir %s
|
||||
|
||||
issues.in_your_repos=Dans vos dépôts
|
||||
@@ -143,11 +143,13 @@ social_register_hepler_msg=Déjà enregistré ? Associez-le !
|
||||
disable_register_prompt=Désolé, les enregistrements ont été désactivés. Veuillez contacter l'administrateur du site.
|
||||
disable_register_mail=Désolé, la Confirmation par Mail des Enregistrements a été désactivée.
|
||||
remember_me=Se souvenir de moi
|
||||
forgot_password=Mot de Passe oublié
|
||||
forget_password=Mot de Passe oublié ?
|
||||
forgot_password=Mot de passe oublié
|
||||
forget_password=Mot de passe oublié ?
|
||||
sign_up_now=Pas de compte ? Inscrivez-vous maintenant.
|
||||
confirmation_mail_sent_prompt=Un nouveau mail de confirmation à été envoyé à <b>%s</b>. Veuillez vérifier votre boîte de réception dans un délai de %d heures pour compléter votre enregistrement.
|
||||
active_your_account=Activer votre Compte
|
||||
active_your_account=Activer votre compte
|
||||
prohibit_login=Login Prohibited
|
||||
prohibit_login_desc=Your account is prohibited to login, please contact site admin.
|
||||
resent_limit_prompt=Désolé, vos tentatives d'activation sont trop fréquentes. Veuillez réessayer dans 3 minutes.
|
||||
has_unconfirmed_mail=Bonjour %s, votre adresse e-mail (<b>%s</b>) n'a pas été confirmée. Si vous n'avez reçu aucun mail de confirmation ou souhaitez renouveler l'envoi, cliquez sur le bouton ci-dessous.
|
||||
resend_mail=Cliquez ici pour renvoyer un mail de confirmation
|
||||
@@ -157,6 +159,7 @@ reset_password=Réinitialiser le mot de passe
|
||||
invalid_code=Désolé, votre code de confirmation est invalide ou a expiré.
|
||||
reset_password_helper=Cliquez ici pour réinitialiser votre mot de passe
|
||||
password_too_short=Le mot de passe doit contenir 6 caractères minimum.
|
||||
non_local_account=Les comptes non-locaux ne peuvent pas changer leur mot de passe via Gogs.
|
||||
|
||||
[mail]
|
||||
activate_account=Veuillez activer votre compte
|
||||
@@ -212,15 +215,14 @@ invalid_ssh_key=Désolé, impossible de valider votre clé SSH : %s
|
||||
unable_verify_ssh_key=Gogs n'a pu vérifier la validité de votre clé SSH, même si nous partons du principe qu'elle le soit. Cela-dit, veuillez vous en assurer.
|
||||
auth_failed=Échec d'authentification : %s
|
||||
|
||||
still_own_repo=Votre compte comporte toujours des propriétés du dépôt. Vous devez d'abord les supprimer ou les transférer.
|
||||
still_has_org=Votre compte contient toujours au moins une adhésion à une organisation, vous devez quitter ou supprimer votre adhésion.
|
||||
org_still_own_repo=Cette organisation comporte toujours des propriétés du dépôt. Vous devez d'abord les supprimer ou les transférer.
|
||||
still_own_repo=Votre compte est toujours propriétaire d'un ou plusieurs dépôts. Vous devez d'abord les supprimer ou les transférer.
|
||||
still_has_org=Votre compte fait toujours partie d'une ou plusieurs organisations. Vous devez d'abord les quitter ou les supprimer.
|
||||
org_still_own_repo=Cette organisation est toujours propriétaire d'un ou plusieurs dépôts. Vous devez d'abord les supprimer ou les transférer.
|
||||
|
||||
target_branch_not_exist=La branche cible n'existe pas.
|
||||
|
||||
[user]
|
||||
change_avatar=Changez d'avatar via gravatar.com
|
||||
change_custom_avatar=Changez votre avatar dans les paramètres
|
||||
change_avatar=Changer votre avatar
|
||||
join_on=Inscrit le
|
||||
repositories=Dépôts
|
||||
activity=Activité publique
|
||||
@@ -240,7 +242,7 @@ ssh_keys=Clés SSH
|
||||
social=Réseaux Sociaux
|
||||
applications=Applications
|
||||
orgs=Organisations
|
||||
delete=Supprimer le Compte
|
||||
delete=Supprimer le compte
|
||||
uid=ID d'Utilisateur
|
||||
|
||||
public_profile=Profil public
|
||||
@@ -256,7 +258,7 @@ change_username_prompt=Cette modification affectera la manière dont les liens s
|
||||
continue=Continuer
|
||||
cancel=Annuler
|
||||
|
||||
enable_custom_avatar=Activer l'Avatar personnalisé
|
||||
enable_custom_avatar=Activer l'avatar personnalisé
|
||||
choose_new_avatar=Sélectionner un nouvel avatar
|
||||
update_avatar=Mettre à jour l'avatar
|
||||
delete_current_avatar=Supprimer l'avatar actuel
|
||||
@@ -265,21 +267,21 @@ update_avatar_success=Votre avatar a été mis à jour avec succès.
|
||||
|
||||
change_password=Modifier le mot de passe
|
||||
old_password=Mot de passe actuel
|
||||
new_password=Nouveau Mot de Passe
|
||||
new_password=Nouveau mot de passe
|
||||
retype_new_password=Retapez le nouveau mot de passe
|
||||
password_incorrect=Mot de passe actuel incorrect.
|
||||
change_password_success=Mot de passe modifié avec succès. Vous pouvez à présent vous connecter avec le nouveau mot de passe.
|
||||
password_change_disabled=Les utilisateurs non-locaux n'ont pas le droit de modifier leur mot de passe.
|
||||
|
||||
emails=Adresses E-mail
|
||||
emails=Adresses e-mail
|
||||
manage_emails=Gérer les adresses e-mail
|
||||
email_desc=Votre adresse e-mail principale sera utilisée pour les notifications et d'autres opérations.
|
||||
primary=Principale
|
||||
primary_email=Définir comme principale
|
||||
delete_email=Supprimer
|
||||
email_deletion=Suppression de l'adresse mél
|
||||
email_deletion=Suppression de l'adresse e-mail
|
||||
email_deletion_desc=Supprimer cette adresse e-mail supprimera les informations associées à votre compte. Voulez-vous continuer ?
|
||||
email_deletion_success=L'adresse mél a été supprimée avec succès !
|
||||
email_deletion_success=L'adresse e-mail a été supprimée avec succès !
|
||||
add_new_email=Ajouter une nouvelle adresse e-mail
|
||||
add_email=Ajouter un e-mail
|
||||
add_email_confirmation_sent=Une nouvelle confirmation d'adresse e-mail a été envoyé à '%s', veuillez vérifier votre boîte de réception dans un délai de %d heures pour terminer le processus de confirmation.
|
||||
@@ -330,7 +332,7 @@ delete_account_desc=Ce compte sera supprimé définitivement. Voulez-vous contin
|
||||
|
||||
[repo]
|
||||
owner=Propriétaire
|
||||
repo_name=Nom du Dépôt
|
||||
repo_name=Nom du dépôt
|
||||
repo_name_helper=Idéalement, le nom d'un dépot devrait être court, mémorable et <strong>unique</strong>.
|
||||
visibility=Visibilité
|
||||
visiblity_helper=Ce dépôt est <span class="ui red text"> privé</span>
|
||||
@@ -350,6 +352,8 @@ readme_helper=Sélectionnez un modèle de readme
|
||||
auto_init=Initialiser ce dépôt avec le modèle et les fichiers sélectionnés
|
||||
create_repo=Créer un dépôt
|
||||
default_branch=Branche par défaut
|
||||
mirror_prune=Purger
|
||||
mirror_prune_desc=Supprimez toute référence de suivi à distance qui n'existe plus sur le dépôt distant
|
||||
mirror_interval=Intervalle du miroir (heure)
|
||||
mirror_address=Adresse du miroir
|
||||
mirror_address_desc=Veuillez inclure les informations d'identification nécessaires dans l'adresse.
|
||||
@@ -372,7 +376,7 @@ migrate.invalid_local_path=Chemin local non valide, non existant ou n'étant pas
|
||||
migrate.failed=Echec de migration: %v
|
||||
|
||||
mirror_from=miroir de
|
||||
forked_from=scindé depuis
|
||||
forked_from=forké depuis
|
||||
fork_from_self=Vous ne pouvez pas forker un dépôt que vous possédez déja !
|
||||
copy_link=Copier
|
||||
copy_link_success=Copié!
|
||||
@@ -400,13 +404,14 @@ tags=Tags
|
||||
issues=Tickets
|
||||
pulls=Pull Requests
|
||||
labels=Etiquettes
|
||||
milestones=Étapes
|
||||
milestones=Jalons
|
||||
commits=Commits
|
||||
releases=Publications
|
||||
file_raw=Raw
|
||||
file_history=Historique
|
||||
file_view_raw=Voir le Raw
|
||||
file_permalink=Lien permanent
|
||||
file_too_large=This file is too large to be shown
|
||||
|
||||
commits.commits=Commits
|
||||
commits.search=Rechercher des commits
|
||||
@@ -425,7 +430,7 @@ issues.new.milestone=Étape
|
||||
issues.new.no_milestone=Pas d'étape
|
||||
issues.new.clear_milestone=Effacer l'étape
|
||||
issues.new.open_milestone=Ouvrir l'étape
|
||||
issues.new.closed_milestone=Étapes fermées
|
||||
issues.new.closed_milestone=Jalons fermés
|
||||
issues.new.assignee=Affecté à
|
||||
issues.new.clear_assignee=Supprimer les assignataires
|
||||
issues.new.no_assignee=Pas d'assignataire
|
||||
@@ -437,7 +442,7 @@ issues.open_tab=%d Ouvert
|
||||
issues.close_tab=%d Fermé
|
||||
issues.filter_label=Étiquette
|
||||
issues.filter_label_no_select=Aucun étiquette sélectionnée
|
||||
issues.filter_milestone=Étape
|
||||
issues.filter_milestone=Jalon
|
||||
issues.filter_milestone_no_select=Aucun jalon sélectionné
|
||||
issues.filter_assignee=Assigné
|
||||
issues.filter_assginee_no_select=Pas d'assignataire selectionné
|
||||
@@ -561,6 +566,10 @@ wiki.last_updated=Dernière mise à jour: %s
|
||||
settings=Paramètres
|
||||
settings.options=Options
|
||||
settings.collaboration=Collaboration
|
||||
settings.collaboration.admin=Administrateur
|
||||
settings.collaboration.write=Écrire
|
||||
settings.collaboration.read=Lire
|
||||
settings.collaboration.undefined=Indéfini
|
||||
settings.hooks=Webhooks
|
||||
settings.githooks=Git Hooks
|
||||
settings.basic_settings=Paramètres de base
|
||||
@@ -575,6 +584,9 @@ settings.external_wiki_url_desc=Les visiteurs seront redirigés vers cette URL l
|
||||
settings.issues_desc=Activer le bug-tracker léger intégré
|
||||
settings.use_external_issue_tracker=Utiliser un bug-tracker externe
|
||||
settings.tracker_url_format=Format d'URL du bug tracker
|
||||
settings.tracker_issue_style=Style de nommage des bugs du tracker externe :
|
||||
settings.tracker_issue_style.numeric=Numérique <span class="ui light grey text">(1234)</span>
|
||||
settings.tracker_issue_style.alphanumeric=Alphanumérique <span class="ui light grey text"> (ABC-123, DEFG-234,...)</span>
|
||||
settings.tracker_url_format_desc=Vous pouvez utiliser l'espace réservé <code>{user} {repo} {index}</code> pour le nom d'utilisateur, le nom du dépôt et le numéro de bug.
|
||||
settings.pulls_desc=Activer les pull requests pour accepter les contributions publiques
|
||||
settings.danger_zone=Zone de danger
|
||||
@@ -586,7 +598,7 @@ settings.convert_confirm=Confirmer la conversion
|
||||
settings.convert_succeed=Le dépôt a été converti avec succès en dépôt ordinaire.
|
||||
settings.transfer=Changer de propriétaire
|
||||
settings.transfer_desc=Transférer ce dépôt à un autre utilisateur ou une organisation dont vous possédez des droits d'administrateur.
|
||||
settings.transfer_notices_1=-Vous perdrez l'accès si le nouveau propriétaire est un utilisateur individuel.
|
||||
settings.transfer_notices_1=- Vous perdrez l'accès si le nouveau propriétaire est un utilisateur individuel.
|
||||
settings.transfer_notices_2=- Vous conserverez l'accès si le nouveau propriétaire est une organisation et que vous y appartenez.
|
||||
settings.transfer_form_title=Veuillez recopier le texte suivant afin de confirmer votre opération :
|
||||
settings.wiki_delete=Effacer les données du Wiki
|
||||
@@ -597,9 +609,7 @@ settings.delete=Supprimer ce dépôt
|
||||
settings.delete_desc=Attention, cette action est action irréversible. Soyez sûr de vous.
|
||||
settings.delete_notices_1=- Cette opération <strong>ne peut pas </strong> être annulée.
|
||||
settings.delete_notices_2=- Cette opération supprimera définitivement le dépôt, y compris les données Git, les tickets, les commentaires et les accès des collaborateurs.
|
||||
settings.delete_notices_fork_1=- Si ce dépôt est public, tous les forks vont devenir indépendant après sa suppression.
|
||||
settings.delete_notices_fork_2=-Si ce dépôt est privé, tous les forks seront supprimés en même temps.
|
||||
settings.delete_notices_fork_3=-Si vous souhaitez conserver tous les forks après suppression, veuillez tout d'abord modifier la visibilité de ce dépôt en public.
|
||||
settings.delete_notices_fork_1=-Tous les forks deviendront indépendants après l’effacement.
|
||||
settings.deletion_success=Le dépôt a été supprimé avec succès!
|
||||
settings.update_settings_success=Options mises à jour avec succès.
|
||||
settings.transfer_owner=Nouveau propriétaire
|
||||
@@ -683,6 +693,8 @@ diff.show_unified_view=Vue unifiée
|
||||
diff.stats_desc=<strong> %d fichiers modifiés</strong> avec <strong>%d ajouts</strong> et <strong>%d suppressions</strong>
|
||||
diff.bin=BIN
|
||||
diff.view_file=Voir le fichier
|
||||
diff.file_suppressed=File diff suppressed because it is too large
|
||||
diff.too_many_files=Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff
|
||||
|
||||
release.releases=Versions
|
||||
release.new_release=Nouvelle version
|
||||
@@ -708,7 +720,7 @@ release.cancel=Annuler
|
||||
release.publish=Publier
|
||||
release.save_draft=Sauvegarder le Brouillon
|
||||
release.edit_release=Modifier la version
|
||||
release.delete_release=Supprimer Cette Version
|
||||
release.delete_release=Supprimer cette version
|
||||
release.deletion=Suppression de la Version
|
||||
release.deletion_desc=Supprimer cette version supprimera le tag Git correspondant. Voulez-vous continuer ?
|
||||
release.deletion_success=La version à été supprimée avec succès !
|
||||
@@ -716,7 +728,7 @@ release.tag_name_already_exist=Une version avec ce nom de tag existe déjà.
|
||||
release.downloads=Téléchargements
|
||||
|
||||
[org]
|
||||
org_name_holder=Nom d'organisation
|
||||
org_name_holder=Nom de l'organisation
|
||||
org_full_name_holder=Nom complet de l'organisation
|
||||
org_name_helper=Idéalement, un nom d'organisation devrait être court et facilement mémorisable.
|
||||
create_org=Créer une organisation
|
||||
@@ -726,7 +738,7 @@ invite_someone=Inviter quelqu'un
|
||||
teams=Équipes
|
||||
lower_members=Membres
|
||||
lower_repositories=dépôts
|
||||
create_new_team=Créer une Nouvelle Équipe
|
||||
create_new_team=Créer une nouvelle équipe
|
||||
org_desc=Description
|
||||
team_name=Nom d'Équipe
|
||||
team_desc=Description
|
||||
@@ -831,7 +843,7 @@ dashboard.resync_all_update_hooks_success=Tous les hooks de mises à jour des d
|
||||
dashboard.reinit_missing_repos=Réinitialiser tous les dépôts qui ont perdu des fichiers Git
|
||||
dashboard.reinit_missing_repos_success=Tous les enregistrements de dépôts qui ont perdu des fichiers Git ont été réinitialisés avec succès.
|
||||
|
||||
dashboard.server_uptime=Durée de Marche Serveur
|
||||
dashboard.server_uptime=Uptime du serveur
|
||||
dashboard.current_goroutine=Goroutines actuelles
|
||||
dashboard.current_memory_usage=Utilisation Mémoire actuelle
|
||||
dashboard.total_memory_allocated=Mémoire totale allouée
|
||||
@@ -880,6 +892,7 @@ users.edit_account=Modifier le Compte
|
||||
users.max_repo_creation=Nombre maximum de dépôts créés
|
||||
users.max_repo_creation_desc=(Mettre à -1 pour utiliser la limite globale par défaut)
|
||||
users.is_activated=Ce compte est activé
|
||||
users.prohibit_login=This account is prohibited to login
|
||||
users.is_admin=Ce compte possède un niveau d'accès administrateur
|
||||
users.allow_git_hook=Ce compte dispose des autorisations pour créer des crochets de Git
|
||||
users.allow_import_local=Ce compte dispose des permissions nécessaire à l'import des dépôts locaux
|
||||
@@ -910,6 +923,7 @@ auths.enabled=Activé
|
||||
auths.updated=Mis à jour
|
||||
auths.auth_type=Type d'authentification
|
||||
auths.auth_name=Nom de l'authentification
|
||||
auths.security_protocol=Protocole de sécurité
|
||||
auths.domain=Domaine
|
||||
auths.host=Hôte
|
||||
auths.port=Port
|
||||
|
||||
48
conf/locale/locale_it-IT.ini
Executable file → Normal file
48
conf/locale/locale_it-IT.ini
Executable file → Normal file
@@ -148,6 +148,8 @@ forget_password=Password dimenticata?
|
||||
sign_up_now=Bisogno di un account? Iscriviti ora.
|
||||
confirmation_mail_sent_prompt=Una nuova email di conferma è stata inviata a <b>%s</b>, verifica la tua casella di posta entro le prossime %d ore per completare la registrazione.
|
||||
active_your_account=Attiva il tuo Account
|
||||
prohibit_login=Login Prohibited
|
||||
prohibit_login_desc=Your account is prohibited to login, please contact site admin.
|
||||
resent_limit_prompt=Siamo spiacenti, si stanno inviando e-mail di attivazione troppo spesso. Si prega di attendere 3 minuti.
|
||||
has_unconfirmed_mail=Ciao %s, hai un indirizzo di posta elettronica non confermato (<b>%s</b>). Se non hai ricevuto una e-mail di conferma o vuoi riceverla nuovamente, fare clic sul pulsante qui sotto.
|
||||
resend_mail=Clicca qui per inviare nuovamente l'e-mail di attivazione
|
||||
@@ -157,6 +159,7 @@ reset_password=Reimposta la tua Password
|
||||
invalid_code=Siamo spiacenti, il codice di conferma è scaduto o non valido.
|
||||
reset_password_helper=Clicca qui per reimpostare la password
|
||||
password_too_short=La lunghezza della password non può essere meno 6 caratteri.
|
||||
non_local_account=Non-local accounts cannot change passwords through Gogs.
|
||||
|
||||
[mail]
|
||||
activate_account=Per favore attiva il tuo account
|
||||
@@ -219,8 +222,7 @@ org_still_own_repo=Questa organizzazione ha ancora la proprietà del repository,
|
||||
target_branch_not_exist=Il ramo (branch) di destinazione non esiste.
|
||||
|
||||
[user]
|
||||
change_avatar=Cambia il tuo avatar su gravatar.com
|
||||
change_custom_avatar=Cambia il tuo avatar nelle impostazioni
|
||||
change_avatar=Change your avatar
|
||||
join_on=Si è unito il
|
||||
repositories=Repository
|
||||
activity=Attività pubblica
|
||||
@@ -350,6 +352,8 @@ readme_helper=Seleziona un template per il readme
|
||||
auto_init=Inizializzare questo repository con i file e il modello selezionati
|
||||
create_repo=Crea Repository
|
||||
default_branch=Ramo (Branch) predefinito
|
||||
mirror_prune=Prune
|
||||
mirror_prune_desc=Remove any remote-tracking references that no longer exist on the remote
|
||||
mirror_interval=Intervallo Mirror (in ore)
|
||||
mirror_address=Indirizzo del mirror
|
||||
mirror_address_desc=Si prega di includere nell'indirizzo le credenziali utente necessarie.
|
||||
@@ -407,6 +411,7 @@ file_raw=Originale
|
||||
file_history=Cronologia
|
||||
file_view_raw=Vedi originale
|
||||
file_permalink=Permalink
|
||||
file_too_large=This file is too large to be shown
|
||||
|
||||
commits.commits=Commits
|
||||
commits.search=Ricerca una versione
|
||||
@@ -467,8 +472,8 @@ issues.close_comment_issue=Commenta e chiudi
|
||||
issues.reopen_issue=Riapri
|
||||
issues.reopen_comment_issue=Commenta e riapri
|
||||
issues.create_comment=Commento
|
||||
issues.closed_at=`closed <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`reopened <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.closed_at=`chiuso <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`riaperto <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at=`referenced this issue from a commit <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.poster=Autore
|
||||
issues.collaborator=Collaboratori
|
||||
@@ -500,8 +505,8 @@ pulls.no_results=Nessun risultato trovato.
|
||||
pulls.nothing_to_compare=Non c'è niente da confrontare perchè i branch base e head uguali.
|
||||
pulls.has_pull_request=`E' già presente una pull request tra questi due trargets: <a href="%[1]s/pulls/%[3]d">%[2]s#%[3]d</a>`
|
||||
pulls.create=Crea Pull Request
|
||||
pulls.title_desc=wants to merge %[1]d commits from <code>%[2]s</code> into <code>%[3]s</code>
|
||||
pulls.merged_title_desc=merged %[1]d commits from <code>%[2]s</code> into <code>%[3]s</code> %[4]s
|
||||
pulls.title_desc=vorrebbe unire %[1]d commit da <code>%[2]s</code> a <code>%[3]s</code>
|
||||
pulls.merged_title_desc=ha unito %[1]d commit da <code>%[2]s</code> a <code>%[3]s</code> %[4]s
|
||||
pulls.tab_conversation=Conversazione
|
||||
pulls.tab_commits=Commit
|
||||
pulls.tab_files=File modificati
|
||||
@@ -561,6 +566,10 @@ wiki.last_updated=Ultimo aggiornamento: %s
|
||||
settings=Impostazioni
|
||||
settings.options=Opzioni
|
||||
settings.collaboration=Collaborazione
|
||||
settings.collaboration.admin=Admin
|
||||
settings.collaboration.write=Write
|
||||
settings.collaboration.read=Read
|
||||
settings.collaboration.undefined=Undefined
|
||||
settings.hooks=Webhooks
|
||||
settings.githooks=Git Hooks
|
||||
settings.basic_settings=Impostazioni di Base
|
||||
@@ -574,7 +583,10 @@ settings.external_wiki_url=URL Wiki esterno
|
||||
settings.external_wiki_url_desc=I visitatori verranno reindirizzati all'URL quando cliccano sulla scheda.
|
||||
settings.issues_desc=Abilita l'issue tracker builtin leggero
|
||||
settings.use_external_issue_tracker=Utilizza gestore di problemi esterno
|
||||
settings.tracker_url_format=External Issue Tracker URL Format
|
||||
settings.tracker_url_format=Formato URL Gestore Problemi Esterno
|
||||
settings.tracker_issue_style=External Issue Tracker Naming Style:
|
||||
settings.tracker_issue_style.numeric=Numeric <span class="ui light grey text">(1234)</span>
|
||||
settings.tracker_issue_style.alphanumeric=Alphanumeric <span class="ui light grey text">(ABC-123, DEFG-234, ...)</span>
|
||||
settings.tracker_url_format_desc=You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
|
||||
settings.pulls_desc=Abilita le pull requests per accettare contributi pubblici
|
||||
settings.danger_zone=Zona Pericolosa
|
||||
@@ -583,7 +595,7 @@ settings.convert=Converti in Repository Regolare
|
||||
settings.convert_desc=Puoi convertire questo mirror in un repository regolare. Questa operazione non può essere annullata.
|
||||
settings.convert_notices_1=- Questa operazione non potrà essere annullata e convertirà questo mirror in un repository regolare.
|
||||
settings.convert_confirm=Conferma la conversione
|
||||
settings.convert_succeed=Repository has been converted to regular type successfully.
|
||||
settings.convert_succeed=Il repository è stato convertito con successo al formato normale.
|
||||
settings.transfer=Trasferisci proprietà
|
||||
settings.transfer_desc=Trasferisci questa repository a un altro utente o a un'organizzazione nella quale hai diritti d'amministratore.
|
||||
settings.transfer_notices_1=- You will lose access if new owner is a individual user.
|
||||
@@ -591,15 +603,13 @@ settings.transfer_notices_2=- You will conserve access if new owner is an organi
|
||||
settings.transfer_form_title=Per favore inserisci le informazioni seguenti per confermare l'operazione:
|
||||
settings.wiki_delete=Elimina i dati della Wiki
|
||||
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
|
||||
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
|
||||
settings.wiki_delete_notices_1=Questo eliminerà e disabiliterà la wiki per %s
|
||||
settings.wiki_deletion_success=I dati della wiki del repository sono stati eliminati con successo.
|
||||
settings.delete=Elimina questo repository
|
||||
settings.delete_desc=Una volta che hai cancellato il repository, non puoi tornare indietro. Si prega di fare attenzione.
|
||||
settings.delete_notices_1=-Questa operazione <strong>NON PUÒ</strong> essere annullata.
|
||||
settings.delete_notices_2=-Questa operazione eliminerà definitivamente il tutto il contenuto del repository, inclusi i dati di Git, incidenti, commenti e accessi dei collaboratori.
|
||||
settings.delete_notices_fork_1=-Se questo repository è pubblico, tutti i fork diventeranno indipendenti dopo la sua cancellazione.
|
||||
settings.delete_notices_fork_2=-Se questo repository è privato, tutti fork verranno rimossi assieme ad esso.
|
||||
settings.delete_notices_fork_3=- Se vuoi mantenere i forks dopo la cancellazione, per piacere cambia la visibilità di questo repository in pubblica.
|
||||
settings.delete_notices_fork_1=- All forks will become independent after deletion.
|
||||
settings.deletion_success=Il repository è stato eliminato con successo!
|
||||
settings.update_settings_success=Le opzioni repository sono state aggiornate con successo.
|
||||
settings.transfer_owner=Nuovo Proprietario
|
||||
@@ -619,7 +629,7 @@ settings.add_webhook=Aggiungi Webhook
|
||||
settings.hooks_desc=I Webhooks sono molto simili a un basilare evento trigger HTTP POST. Ogni volta che qualcosa si verifica in Gogs, tratteremo la notifica all'host di destinazione specificato. Ulteriori informazioni in questa <a target="_blank" href="%s">Guida ai Webhooks</a>.
|
||||
settings.webhook_deletion=Elimina Webhook
|
||||
settings.webhook_deletion_desc=Delete this webhook will remove its information and all delivery history. Do you want to continue?
|
||||
settings.webhook_deletion_success=Webhook has been deleted successfully!
|
||||
settings.webhook_deletion_success=Il Webhook è stato eliminato con successo!
|
||||
settings.webhook.test_delivery=Test di consegna
|
||||
settings.webhook.test_delivery_desc=Send a fake push event delivery to test your webhook settings
|
||||
settings.webhook.test_delivery_success=Test webhook has been added to delivery queue. It may take few seconds before it shows up in the delivery history.
|
||||
@@ -683,6 +693,8 @@ diff.show_unified_view=Visualizzazione unificata
|
||||
diff.stats_desc=<strong>%d ha cambiato i file</strong> con <strong>%d aggiunte</strong> e <strong>%d eliminazioni</strong>
|
||||
diff.bin=BIN
|
||||
diff.view_file=Vedi File
|
||||
diff.file_suppressed=File diff suppressed because it is too large
|
||||
diff.too_many_files=Some files were not shown because too many files changed in this diff
|
||||
|
||||
release.releases=Rilasci
|
||||
release.new_release=Nuovo Rilascio
|
||||
@@ -880,6 +892,7 @@ users.edit_account=Modifica Account
|
||||
users.max_repo_creation=Limite massimo per la creazione di Repository
|
||||
users.max_repo_creation_desc=(Inserire -1 per usare il limite globale di default)
|
||||
users.is_activated=Questo account è attivato
|
||||
users.prohibit_login=This account is prohibited to login
|
||||
users.is_admin=Questo account ha permessi di amministratore
|
||||
users.allow_git_hook=Questo account ha il permesso di creare hooks di Git
|
||||
users.allow_import_local=Questo account dispone delle autorizzazioni per importare repository locali
|
||||
@@ -910,6 +923,7 @@ auths.enabled=Attivo
|
||||
auths.updated=Aggiornato
|
||||
auths.auth_type=Tipo di autenticazione
|
||||
auths.auth_name=Nome di autenticazione
|
||||
auths.security_protocol=Security Protocol
|
||||
auths.domain=Dominio
|
||||
auths.host=Host
|
||||
auths.port=Porta
|
||||
@@ -1067,7 +1081,7 @@ comment_issue=`ha commentato il problema <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`merged pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=ha trasferito il repository <code>%s</code> a <a href="%s">%s</a>
|
||||
push_tag=ha pushato il tag <a href="%s/src/%s">%[2]s</a> a <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=View comparison for these %d commits
|
||||
compare_commits=Visualizza comparazione tra questi %d commit
|
||||
|
||||
[tool]
|
||||
ago=fa
|
||||
@@ -1091,8 +1105,8 @@ raw_seconds=secondi
|
||||
raw_minutes=minuti
|
||||
|
||||
[dropzone]
|
||||
default_message=Drop files here or click to upload.
|
||||
invalid_input_type=You can't upload files of this type.
|
||||
file_too_big=File size ({{filesize}} MB) exceeds maximum size ({{maxFilesize}} MB).
|
||||
default_message=Trascina i file qui o clicca per caricare.
|
||||
invalid_input_type=Non è possibile caricare file di questo tipo.
|
||||
file_too_big=La dimensione del file ({{filesize}} MB) supera la dimensione massima ({{maxFilesize}} MB).
|
||||
remove_file=Rimuovi file
|
||||
|
||||
|
||||
112
conf/locale/locale_ja-JP.ini
Executable file → Normal file
112
conf/locale/locale_ja-JP.ini
Executable file → Normal file
@@ -2,7 +2,7 @@ app_desc=Go言語で実装したセルフホストGitサービス
|
||||
|
||||
home=ホーム
|
||||
dashboard=ダッシュボード
|
||||
explore=エスクプローラ
|
||||
explore=エクスプローラ
|
||||
help=ヘルプ
|
||||
sign_in=サインイン
|
||||
sign_out=サインアウト
|
||||
@@ -21,7 +21,7 @@ username=ユーザ名
|
||||
email=E-mail
|
||||
password=パスワード
|
||||
re_type=再入力
|
||||
captcha=キャプチャ
|
||||
captcha=CAPTCHA
|
||||
|
||||
repository=リポジトリ
|
||||
organization=組織
|
||||
@@ -35,8 +35,8 @@ manage_org=組織を管理
|
||||
admin_panel=管理者パネル
|
||||
account_settings=アカウント設定
|
||||
settings=設定
|
||||
your_profile=あなたのプロファイル
|
||||
your_settings=あなたの設定
|
||||
your_profile=プロフィール
|
||||
your_settings=設定
|
||||
|
||||
activities=アクティビティ
|
||||
pull_requests=プルリクエスト
|
||||
@@ -72,9 +72,9 @@ repo_path_helper=すべての Git リモート リポジトリはこのディレ
|
||||
run_user=実行ユーザ
|
||||
run_user_helper=ユーザーはリポジトリ ルートパスへのアクセス、及びGogs を実行する権限を所有する必要があります。
|
||||
domain=ドメイン
|
||||
domain_helper=これはSSHクローンURLに影響する。
|
||||
domain_helper=これはSSH用クローンURLに影響します。
|
||||
ssh_port=SSH ポート
|
||||
ssh_port_helper=あならのSSHサーバおポート番号、SSH機能を無効するにはここを空白のままにしてください。
|
||||
ssh_port_helper=SSHサーバーを使用する場合はポート番号を入力してください。 空白にした場合は無効化されます。
|
||||
http_port=HTTP ポート
|
||||
http_port_helper=アプリケーションが待ち受けするポート番号。
|
||||
app_url=アプリケーションの URL
|
||||
@@ -83,7 +83,7 @@ log_root_path=ログのパス
|
||||
log_root_path_helper=ログファイルを書き込むディレクトリ。
|
||||
|
||||
optional_title=オプション設定
|
||||
email_title=E-mailサービス設定
|
||||
email_title=メールサービス設定
|
||||
smtp_host=SMTP ホスト
|
||||
smtp_from=差出人
|
||||
smtp_from_helper=送信者メールアドレス、RFC 5322。フォーマットはメールアドレスのみ、または"Name" <email@example.com>。
|
||||
@@ -123,31 +123,33 @@ invalid_log_root_path=ログのルートパスがむこうです: %v
|
||||
uname_holder=ユーザー名またはEメール
|
||||
password_holder=パスワード
|
||||
switch_dashboard_context=ダッシュ ボードのコンテキストを切替
|
||||
my_repos=私のリポジトリ
|
||||
my_repos=自分のリポジトリ
|
||||
collaborative_repos=共同リポジトリ
|
||||
my_orgs=私の組織
|
||||
my_mirrors=私のミラー
|
||||
my_orgs=自分の組織
|
||||
my_mirrors=自分のミラー
|
||||
view_home=ビュー %s
|
||||
|
||||
issues.in_your_repos=あなたのリポジトリ
|
||||
|
||||
[explore]
|
||||
repos=リポジトリ
|
||||
users=Users
|
||||
search=Search
|
||||
users=ユーザ
|
||||
search=検索
|
||||
|
||||
[auth]
|
||||
create_new_account=新規アカウントを作成
|
||||
register_hepler_msg=すでにアカウントをお持ちですか?今すぐログイン !
|
||||
social_register_hepler_msg=すでにアカウントをお持ちですか?今すぐバインド !
|
||||
disable_register_prompt=申し訳ありませんが、登録が無効になっています。サイト管理者に問い合わせてください。
|
||||
register_hepler_msg=既にアカウントをお持ちですか?今すぐログインしましょう!
|
||||
social_register_hepler_msg=既にアカウントをお持ちですか?連携しましょう!
|
||||
disable_register_prompt=申し訳ありませんが、現在登録は受け付けておりません。サイトの管理者にお問い合わせください。
|
||||
disable_register_mail=申し訳ありませんが、登録メールの確認機能が無効になっています。
|
||||
remember_me=ログイン状態を保持する
|
||||
remember_me=ログインしたままにする
|
||||
forgot_password=パスワードを忘れた
|
||||
forget_password=パスワードを忘れた?
|
||||
sign_up_now=アカウントが必要ですか?今すぐサインアップ
|
||||
forget_password=パスワードを忘れましたか?
|
||||
sign_up_now=アカウントが必要ですか?今すぐ登録しましょう!
|
||||
confirmation_mail_sent_prompt=新しい確認メールを <b>%s</b> に送りました。登録を完了させるために、%d時間以内にあなたのメールボックスを確認してください。
|
||||
active_your_account=アカウントをアクティブ
|
||||
active_your_account=アカウントを有効化
|
||||
prohibit_login=Login Prohibited
|
||||
prohibit_login_desc=Your account is prohibited to login, please contact site admin.
|
||||
resent_limit_prompt=申し訳ありませんが、アクティベーションメールは頻繁に送信しています。3 分お待ちください。
|
||||
has_unconfirmed_mail=こんにちは %s さん、あなたの電子メール アドレス (<b>%s</b>) は未確認です。もし確認メールをまだ確認できていないか、改めて再送信する場合は、下のボタンをクリックしてください。
|
||||
resend_mail=アクティベーションメールを再送信するにはここをクリック
|
||||
@@ -157,6 +159,7 @@ reset_password=パスワードリセット
|
||||
invalid_code=申し訳ありませんが、確認用コードが期限切れまたは無効です。
|
||||
reset_password_helper=パスワードをリセットするにはここをクリック
|
||||
password_too_short=6文字未満のパスワードは設定できません。
|
||||
non_local_account=Non-local accounts cannot change passwords through Gogs.
|
||||
|
||||
[mail]
|
||||
activate_account=あなたのアカウントを有効にしてください。
|
||||
@@ -219,8 +222,7 @@ org_still_own_repo=この組織はまだリポジトリの所有しています
|
||||
target_branch_not_exist=ターゲットブランチが存在しない
|
||||
|
||||
[user]
|
||||
change_avatar=gravatar.com で自分のアバターを変更
|
||||
change_custom_avatar=設定で自分のアバターを変更
|
||||
change_avatar=アバターを変更
|
||||
join_on=参加しました
|
||||
repositories=リポジトリ
|
||||
activity=パブリック・アクティビティ
|
||||
@@ -310,7 +312,7 @@ social_desc=これは関連付けられたソーシャルアカウントのリ
|
||||
unbind=バインド解除
|
||||
unbind_success=SNSアカウントがバインドされていない。
|
||||
|
||||
manage_access_token=個人のアクセス トークンを管理
|
||||
manage_access_token=パーソナルアクセス トークンを管理
|
||||
generate_new_token=新しいトークンを生成
|
||||
tokens_desc=生成したトークンを利用して Gogs の API にアクセスすることができます。
|
||||
new_token_desc=今のところ、全てのトークンはあなたのアカウントにフルアクセスできます。
|
||||
@@ -323,7 +325,7 @@ access_token_deletion_desc=パーソナルアクセストークンを削除す
|
||||
delete_token_success=パーソナルアクセストークンは正常に削除されました!同時にあなたのアプリケーションを更新することを忘れないでください。
|
||||
|
||||
delete_account=アカウントを削除
|
||||
delete_prompt=この操作はあなたのアカウントを完全に削除し、復旧<strong>できない</strong> !
|
||||
delete_prompt=この操作をするとアカウントが完全に削除され、<strong>二度と元に戻すことができなくなります</strong> !
|
||||
confirm_delete_account=削除の確認
|
||||
delete_account_title=アカウントの削除
|
||||
delete_account_desc=このアカウントは永久に削除しようとしている、継続しますか?
|
||||
@@ -331,15 +333,15 @@ delete_account_desc=このアカウントは永久に削除しようとしてい
|
||||
[repo]
|
||||
owner=オーナー
|
||||
repo_name=リポジトリ名
|
||||
repo_name_helper=偉大なリポジトリ名は短い。思い出に残り、そして<strong>一意</strong>だ。
|
||||
visibility=ビジビリティ
|
||||
repo_name_helper=短くて分かりやすく<strong>重複しない</strong>リポジトリ名を決めてください。
|
||||
visibility=公開/非公開
|
||||
visiblity_helper=このリポジトリは<span class="ui red text">プライベート</span>です。
|
||||
visiblity_helper_forced=サイト管理者は、強制的にすべての新しいリポジトリを<span class="ui red text"> プライベート</span> にしています。
|
||||
visiblity_fork_helper=(この値の変更はすべてのフォークに適用されます)
|
||||
clone_helper=クローニングのヘルプが必要ですか?<a target="_blank"href="%s"> ヘルプ</a> を参照してください!
|
||||
fork_repo=フォークのリポジトリ
|
||||
clone_helper=クローンに関してお困りであれば<a target="_blank"href="%s"> ヘルプ</a> を参照しましょう。
|
||||
fork_repo=リポジトリをフォーク
|
||||
fork_from=フォーク元
|
||||
fork_visiblity_helper=フォークされたリポジトリは可視状態を変更できません
|
||||
fork_visiblity_helper=フォークされたリポジトリの可視状態は変更できません。
|
||||
repo_desc=説明
|
||||
repo_lang=言語
|
||||
repo_lang_helper=.gitignoreファイルを選択
|
||||
@@ -350,6 +352,8 @@ readme_helper=Readme ファイルのテンプレートを選択
|
||||
auto_init=選択されたファイルおよびテンプレートでリポジトリを初期化
|
||||
create_repo=リポジトリを作成
|
||||
default_branch=デフォルトのブランチ
|
||||
mirror_prune=Prune
|
||||
mirror_prune_desc=Remove any remote-tracking references that no longer exist on the remote
|
||||
mirror_interval=ミラー 間隔(時)
|
||||
mirror_address=ミラー アドレス
|
||||
mirror_address_desc=Please include necessary user credentials in the address.
|
||||
@@ -358,8 +362,8 @@ stargazers=Stargazers
|
||||
forks=フォーク
|
||||
|
||||
form.reach_limit_of_creation=The owner has reached maximum creation limit of %d repositories.
|
||||
form.name_reserved=リポジトリ名 '%s' は予約されています。
|
||||
form.name_pattern_not_allowed=リポジトリ名のパターン '%s' は許可されていません。
|
||||
form.name_reserved=リポジトリ名 '%s' は使用されています。
|
||||
form.name_pattern_not_allowed=リポジトリ名に '%s' は使用できません。
|
||||
|
||||
need_auth=認証が必要
|
||||
migrate_type=マイグレーションの種類
|
||||
@@ -371,7 +375,7 @@ migrate.permission_denied=ローカル リポジトリをインポートする
|
||||
migrate.invalid_local_path=ローカルパスが無効です。存在しないかディレクトリではありません。
|
||||
migrate.failed=移行に失敗しました: %v
|
||||
|
||||
mirror_from=mirror of
|
||||
mirror_from=同期ミラー
|
||||
forked_from=フォーク元
|
||||
fork_from_self=すでにあなたの所有しているリポジトリはフォークできません
|
||||
copy_link=コピー
|
||||
@@ -403,10 +407,11 @@ labels=ラベル
|
||||
milestones=マイルストーン
|
||||
commits=コミット
|
||||
releases=リリース
|
||||
file_raw=生データ
|
||||
file_raw=Raw
|
||||
file_history=履歴
|
||||
file_view_raw=生データを見る
|
||||
file_view_raw=Rawデータを見る
|
||||
file_permalink=パーマリンク
|
||||
file_too_large=This file is too large to be shown
|
||||
|
||||
commits.commits=コミット
|
||||
commits.search=コミットの検索
|
||||
@@ -443,8 +448,8 @@ issues.filter_assignee=アサインされた人
|
||||
issues.filter_assginee_no_select=選択可能な担当者がいない
|
||||
issues.filter_type=タイプ
|
||||
issues.filter_type.all_issues=すべての問題
|
||||
issues.filter_type.assigned_to_you=あなたに割り当てられました。
|
||||
issues.filter_type.created_by_you=あなたが作成しました。
|
||||
issues.filter_type.assigned_to_you=担当中のリポジトリ
|
||||
issues.filter_type.created_by_you=作成したリポジトリ
|
||||
issues.filter_type.mentioning_you=あなたに伝える
|
||||
issues.filter_sort=並べ替え
|
||||
issues.filter_sort.latest=最新
|
||||
@@ -463,7 +468,7 @@ issues.num_comments=%d コメント
|
||||
issues.commented_at=`コメント <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.no_content=まだコンテンツがありません
|
||||
issues.close_issue=閉じる
|
||||
issues.close_comment_issue=コメントと閉じる
|
||||
issues.close_comment_issue=コメントしてクローズ
|
||||
issues.reopen_issue=Reopen
|
||||
issues.reopen_comment_issue=コメントと再開
|
||||
issues.create_comment=コメント
|
||||
@@ -471,7 +476,7 @@ issues.closed_at=`closed <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`reopened <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at=`referenced this issue from a commit <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.poster=ポスター
|
||||
issues.collaborator=Collaborator
|
||||
issues.collaborator=コラボレータ
|
||||
issues.owner=オーナー
|
||||
issues.sign_up_for_free=無料でサインアップ
|
||||
issues.sign_in_require_desc=to join this conversation. Already have an account? <a href="%s">Sign in to comment</a>
|
||||
@@ -561,6 +566,10 @@ wiki.last_updated=最終更新 %s
|
||||
settings=設定
|
||||
settings.options=オプション
|
||||
settings.collaboration=コラボレーション
|
||||
settings.collaboration.admin=Admin
|
||||
settings.collaboration.write=Write
|
||||
settings.collaboration.read=Read
|
||||
settings.collaboration.undefined=Undefined
|
||||
settings.hooks=Webhooks
|
||||
settings.githooks=Git のフック
|
||||
settings.basic_settings=基本設定
|
||||
@@ -575,6 +584,9 @@ settings.external_wiki_url_desc=Visitors will be redirected to URL when they cli
|
||||
settings.issues_desc=組み込み簡易課題トラッカーを有効
|
||||
settings.use_external_issue_tracker=外部課題トラッキングシステムを使用
|
||||
settings.tracker_url_format=外部課題トラッキングツール URLのフォーマット
|
||||
settings.tracker_issue_style=External Issue Tracker Naming Style:
|
||||
settings.tracker_issue_style.numeric=Numeric <span class="ui light grey text">(1234)</span>
|
||||
settings.tracker_issue_style.alphanumeric=Alphanumeric <span class="ui light grey text">(ABC-123, DEFG-234, ...)</span>
|
||||
settings.tracker_url_format_desc=You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
|
||||
settings.pulls_desc=Enable pull requests to accept public contributions
|
||||
settings.danger_zone=危険地帯
|
||||
@@ -597,15 +609,13 @@ settings.delete=このリポジトリを削除
|
||||
settings.delete_desc=リポジトリを削除すると元に戻せません。確実に確認してください。
|
||||
settings.delete_notices_1=-この操作は<strong>元に戻せません</strong> 。
|
||||
settings.delete_notices_2=- This operation will permanently delete the everything of this repository, including Git data, issues, comments and accesses of collaborators.
|
||||
settings.delete_notices_fork_1=- If this repository is public, all forks will become independent after deletion.
|
||||
settings.delete_notices_fork_2=もしプライペートリポジトリの場合、全てのフォークも同時に削除されます。
|
||||
settings.delete_notices_fork_3=- If you want to keep all forks after deletion, please change visibility of this repository to public first.
|
||||
settings.delete_notices_fork_1=- All forks will become independent after deletion.
|
||||
settings.deletion_success=Repository has been deleted successfully!
|
||||
settings.update_settings_success=リポジトリ オプションが更新されました。
|
||||
settings.transfer_owner=新しいオーナー
|
||||
settings.make_transfer=転送
|
||||
settings.transfer_succeed=リポジトリの所有権は正常に転送されました。
|
||||
settings.confirm_delete=削除の確認
|
||||
settings.confirm_delete=削除を確認
|
||||
settings.add_collaborator=新しい共同編集者を追加
|
||||
settings.add_collaborator_success=新しい共同編集者が追加されました。
|
||||
settings.delete_collaborator=Delete
|
||||
@@ -683,6 +693,8 @@ diff.show_unified_view=Unified View
|
||||
diff.stats_desc=共有<strong>%d 個のファイルを変更した</strong>、<strong>%d 個の追加</strong> と <strong>%d 個の削除</strong>を含む
|
||||
diff.bin=BIN
|
||||
diff.view_file=ファイルの表示
|
||||
diff.file_suppressed=File diff suppressed because it is too large
|
||||
diff.too_many_files=Some files were not shown because too many files changed in this diff
|
||||
|
||||
release.releases=リリース
|
||||
release.new_release=新しいリリース
|
||||
@@ -720,7 +732,7 @@ org_name_holder=組織名
|
||||
org_full_name_holder=組織のフルネーム
|
||||
org_name_helper=偉大な組織の名は短く覚えやすいです。
|
||||
create_org=組織を作成
|
||||
repo_updated=更新した
|
||||
repo_updated=最終更新
|
||||
people=人々
|
||||
invite_someone=誰かを招待
|
||||
teams=チーム
|
||||
@@ -748,8 +760,8 @@ settings.change_orgname_prompt=This change will affect how links relate to the o
|
||||
settings.update_avatar_success=組織のアバター画像が正常に更新されました。
|
||||
settings.delete=組織を削除
|
||||
settings.delete_account=この組織を削除
|
||||
settings.delete_prompt=操作はこの組織を完全に削除し、復旧<strong>できない</strong>!
|
||||
settings.confirm_delete_account=削除の確認
|
||||
settings.delete_prompt=この操作をすると組織が完全に削除され、<strong>二度と元に戻すことができなくなります</strong> !
|
||||
settings.confirm_delete_account=削除を確認
|
||||
settings.delete_org_title=組織の削除
|
||||
settings.delete_org_desc=この組織は完全に削除されます、継続しますか?
|
||||
settings.hooks_desc=この組織のもとで <strong>すべてのリポジトリ</strong> に対してトリガーされる webhook を追加します。
|
||||
@@ -880,6 +892,7 @@ users.edit_account=アカウントの編集
|
||||
users.max_repo_creation=Maximum Repository Creation Limit
|
||||
users.max_repo_creation_desc=(Set -1 to use global default limit)
|
||||
users.is_activated=アカウントがアクティブされました
|
||||
users.prohibit_login=This account is prohibited to login
|
||||
users.is_admin=このアカウントには管理者の権限を持つ
|
||||
users.allow_git_hook=このアカウントには Git のフックを作成する権限を持つ
|
||||
users.allow_import_local=This account has permissions to import local repositories
|
||||
@@ -907,9 +920,10 @@ auths.new=新しいソースを追加
|
||||
auths.name=名前
|
||||
auths.type=タイプ
|
||||
auths.enabled=Enabled
|
||||
auths.updated=Updated
|
||||
auths.updated=更新しました
|
||||
auths.auth_type=認証タイプ
|
||||
auths.auth_name=認証名
|
||||
auths.security_protocol=Security Protocol
|
||||
auths.domain=ドメイン
|
||||
auths.host=ホスト
|
||||
auths.port=ポート
|
||||
@@ -1016,7 +1030,7 @@ config.cache_conn=キャッシュ接続
|
||||
config.session_config=セッションの構成
|
||||
config.session_provider=セッション プロバイダー
|
||||
config.provider_config=プロバイダーの構成
|
||||
config.cookie_name=クッキー名
|
||||
config.cookie_name=クッキーの名前
|
||||
config.enable_set_cookie=クッキーの設定を有効にする
|
||||
config.gc_interval_time=GC 間隔
|
||||
config.session_life_time=セッションのライフタイム
|
||||
@@ -1054,8 +1068,8 @@ notices.op=Op。
|
||||
notices.delete_success=システム通知が正常に削除されました。
|
||||
|
||||
[action]
|
||||
create_repo=リポジトリ <a href="%s"> %s</a>を作成しました
|
||||
rename_repo=<code>%[1]s</code> から <a href="%[2]s">[3]s</a> にリポジトリ名を変更した
|
||||
create_repo=がリポジトリ <a href="%s"> %s</a> を作成しました
|
||||
rename_repo=<code>%[1]s</code> から <a href="%[2]s">[3]s</a> にリポジトリ名を変更しました
|
||||
commit_repo=<a href="%[1]s">%[4]s</a>を<a href="%[1]s/src/%[2]s">%[3]s</a>にプッシュしました
|
||||
create_issue=`問題 <a href="%s/issues/%s">%s#%[2]s</a> を開きました`
|
||||
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
@@ -1081,7 +1095,7 @@ now=今
|
||||
1mon=1 ヶ月 %s
|
||||
1y=1 年間 %s
|
||||
seconds=%d 秒 %s
|
||||
minutes=%d 分の %s
|
||||
minutes=%d分%s
|
||||
hours=%d 時間 %s
|
||||
days=%d 日 %s
|
||||
weeks=%d 週間 %s
|
||||
|
||||
24
conf/locale/locale_lv-LV.ini
Executable file → Normal file
24
conf/locale/locale_lv-LV.ini
Executable file → Normal file
@@ -148,6 +148,8 @@ forget_password=Aizmirsi paroli?
|
||||
sign_up_now=Nepieciešams konts? Reģistrējies tagad.
|
||||
confirmation_mail_sent_prompt=Jauns apstiprināšanas e-pasts ir nosūtīts uz <b>%s</b>, lūdzu, pārbaudies savu e-pasta kontu tuvāko %d stundu laikā, lai pabeigtu reģistrācijas procesu.
|
||||
active_your_account=Aktivizēt savu kontu
|
||||
prohibit_login=Login Prohibited
|
||||
prohibit_login_desc=Your account is prohibited to login, please contact site admin.
|
||||
resent_limit_prompt=Atvainojiet, Jūs sūtījāt aktivizācijas e-pastu pārāk bieži. Lūdzu, gaidiet 3 minūtes.
|
||||
has_unconfirmed_mail=Sveiki %s, Jums ir neapstiprināta e-pasta adrese (<b>%s</b>). Ja neesat saņēmis apstiprināšanas e-pastu vai Jums ir nepieciešams nosūtīt jaunu, lūdzu, nospiediet pogu, kas atrodas zemāk.
|
||||
resend_mail=Nospiediet šeit, lai vēlreiz nosūtītu aktivizācijas e-pastu
|
||||
@@ -157,6 +159,7 @@ reset_password=Atjaunot savu paroli
|
||||
invalid_code=Atvainojiet, Jūsu apstiprināšanas kodam ir beidzies derīguma termiņš vai arī tas ir nepareizs.
|
||||
reset_password_helper=Nospiediet šeit, lai atjaunotu paroli
|
||||
password_too_short=Paroles garums nedrīkst būt mazāks par 6.
|
||||
non_local_account=Non-local accounts cannot change passwords through Gogs.
|
||||
|
||||
[mail]
|
||||
activate_account=Lūdzu, aktivizējiet savu kontu
|
||||
@@ -219,8 +222,7 @@ org_still_own_repo=Šī organizācija ir vismaz viena repozitorija īpašnieks,
|
||||
target_branch_not_exist=Mērķa atzars neeksistē
|
||||
|
||||
[user]
|
||||
change_avatar=Mainīt savu profila attēlu vietnē gravatar.com
|
||||
change_custom_avatar=Mainīt savu profila attēlu iestatījumos
|
||||
change_avatar=Change your avatar
|
||||
join_on=Pievienojās
|
||||
repositories=Repozitoriji
|
||||
activity=Publiskā aktivitāte
|
||||
@@ -350,6 +352,8 @@ readme_helper=Izvēlieties faila LasiMani sagatavi
|
||||
auto_init=Inicializēt šo repozitoriju ar izvēlētajiem failiem un sagatavi
|
||||
create_repo=Izveidot repozitoriju
|
||||
default_branch=Noklusējuma atzars
|
||||
mirror_prune=Prune
|
||||
mirror_prune_desc=Remove any remote-tracking references that no longer exist on the remote
|
||||
mirror_interval=Spoguļošanas intervāls (stundās)
|
||||
mirror_address=Spoguļa adrese
|
||||
mirror_address_desc=Lūdzu iekļaujiet adresē nepieciešamo lietotājvārdu/paroli.
|
||||
@@ -407,6 +411,7 @@ file_raw=Neapstrādāts
|
||||
file_history=Vēsture
|
||||
file_view_raw=Rādīt neapstrādātu
|
||||
file_permalink=Patstāvīgā saite
|
||||
file_too_large=This file is too large to be shown
|
||||
|
||||
commits.commits=Revīzijas
|
||||
commits.search=Meklēt revīzijas
|
||||
@@ -561,6 +566,10 @@ wiki.last_updated=Pēdējo reizi labota %s
|
||||
settings=Iestatījumi
|
||||
settings.options=Opcijas
|
||||
settings.collaboration=Sadarbība
|
||||
settings.collaboration.admin=Admin
|
||||
settings.collaboration.write=Write
|
||||
settings.collaboration.read=Read
|
||||
settings.collaboration.undefined=Undefined
|
||||
settings.hooks=Tīmekļa āķi
|
||||
settings.githooks=Git āķi
|
||||
settings.basic_settings=Pamatiestatījumi
|
||||
@@ -575,6 +584,9 @@ settings.external_wiki_url_desc=Apmeklētāji tiks novirzīti uz adresi, kad vi
|
||||
settings.issues_desc=Iespējot iebūvētu vieglu problēmu sekotāju
|
||||
settings.use_external_issue_tracker=Izmantot ārējo problēmu sekotāju
|
||||
settings.tracker_url_format=Ārējā problēmu sekotāja adreses formāts
|
||||
settings.tracker_issue_style=External Issue Tracker Naming Style:
|
||||
settings.tracker_issue_style.numeric=Numeric <span class="ui light grey text">(1234)</span>
|
||||
settings.tracker_issue_style.alphanumeric=Alphanumeric <span class="ui light grey text">(ABC-123, DEFG-234, ...)</span>
|
||||
settings.tracker_url_format_desc=Jūs varat izmantot <code>{user}{repo}{index}</code> lietotājvārdam, repozitorija nosaukumam un problēmas identifikātoram.
|
||||
settings.pulls_desc=Iespējot izmaiņu pieprasījumus lai saņemtu publiskus ieguldījumus
|
||||
settings.danger_zone=Bīstamā zona
|
||||
@@ -597,9 +609,7 @@ settings.delete=Dzēst šo repozitoriju
|
||||
settings.delete_desc=Dzēšot repozitoriju, tā datus vairs nebūs iespējams atgūt. Pirms dzēšanas pārliecinieites vai patiešām vēlaties to darīt.
|
||||
settings.delete_notices_1=- Šī darbība ir <strong>NEATGRIEZENISKA</strong>.
|
||||
settings.delete_notices_2=- Šī darbība neatgriezeniski izdzēsīs visus šī repozitorija datus, tai skaitā Git datus, problēmu ziņojumus, komentārus un definētās piekļuves tiesības.
|
||||
settings.delete_notices_fork_1=- Ja repozitorijs ir publisks, visi atdalītie repozitoriji kļūs neatkarīgi.
|
||||
settings.delete_notices_fork_2=- Ja repozitorijs ir privāts, tiks dzēsti arī visi atdalītie repozitoriji.
|
||||
settings.delete_notices_fork_3=- Ja vēlaties saglabāt atdalīts repozitorijus pēc dzēšanas, sākumā nomainiet repozitorija redzamību uz publisku.
|
||||
settings.delete_notices_fork_1=- All forks will become independent after deletion.
|
||||
settings.deletion_success=Repozitorijs tika veiksmīgi dzēsts!
|
||||
settings.update_settings_success=Repozitorija opcijas ir veiksmīgi saglabātas.
|
||||
settings.transfer_owner=Jaunais īpašnieks
|
||||
@@ -683,6 +693,8 @@ diff.show_unified_view=Apvienotais skats
|
||||
diff.stats_desc=<strong>%d mainītis faili</strong> ar <strong>%d papildinājumiem</strong> un <strong>%d dzēšanām</strong>
|
||||
diff.bin=BIN
|
||||
diff.view_file=Parādīt failu
|
||||
diff.file_suppressed=File diff suppressed because it is too large
|
||||
diff.too_many_files=Some files were not shown because too many files changed in this diff
|
||||
|
||||
release.releases=Laidieni
|
||||
release.new_release=Jauns laidiens
|
||||
@@ -880,6 +892,7 @@ users.edit_account=Labot kontu
|
||||
users.max_repo_creation=Maksimāls repozitoriju veidošanas limits
|
||||
users.max_repo_creation_desc=(Uzlikt -1 lai izmantotu globālu limitu pēc noklusējuma)
|
||||
users.is_activated=Konts ir aktivizēts
|
||||
users.prohibit_login=This account is prohibited to login
|
||||
users.is_admin=Šim kontam ir administratora piekļuves tiesības
|
||||
users.allow_git_hook=Šim kontam ir tiesības pievienot/labot Git āķus
|
||||
users.allow_import_local=Šim kontam ir tiesības importēt lokālus repozitorijus
|
||||
@@ -910,6 +923,7 @@ auths.enabled=Iespējota
|
||||
auths.updated=Atjaunināta
|
||||
auths.auth_type=Autentifikācijas tips
|
||||
auths.auth_name=Autentifikācijas nosaukums
|
||||
auths.security_protocol=Security Protocol
|
||||
auths.domain=Domēns
|
||||
auths.host=Resursdators
|
||||
auths.port=Ports
|
||||
|
||||
136
conf/locale/locale_nl-NL.ini
Executable file → Normal file
136
conf/locale/locale_nl-NL.ini
Executable file → Normal file
@@ -148,6 +148,8 @@ forget_password=Wachtwoord vergeten?
|
||||
sign_up_now=Een account nodig? Meld u nu aan.
|
||||
confirmation_mail_sent_prompt=Een bevestigingsemail is gestuurd naar <b>%s</b>, Bevestig u aanvraag binnen %d uren om uw registratie te voltooien.
|
||||
active_your_account=Activeer uw account
|
||||
prohibit_login=Login Prohibited
|
||||
prohibit_login_desc=Your account is prohibited to login, please contact site admin.
|
||||
resent_limit_prompt=Sorry, u heeft te snel na elkaar een aanvraag gedaan voor een activatie mail. Wacht drie minuten voor uw volgende aanvraag.
|
||||
has_unconfirmed_mail=Beste %s, u heeft een onbevestigd e-mailadres (<b>%s</b>). Als u nog geen bevestiging heeft ontvangen, of u een nieuwe aanvraag wilt doen, klik dan op de onderstaande knop.
|
||||
resend_mail=Klik hier om uw activatie mail nog een keer te verzenden
|
||||
@@ -157,6 +159,7 @@ reset_password=Reset uw wachtwoord
|
||||
invalid_code=Sorry, uw bevestigingscode is verlopen of niet meer geldig.
|
||||
reset_password_helper=Klik hier om uw wachtwoord opnieuw in te stellen.
|
||||
password_too_short=De lengte van uw wachtwoord moet minimaal zes karakters zijn.
|
||||
non_local_account=Non-local accounts cannot change passwords through Gogs.
|
||||
|
||||
[mail]
|
||||
activate_account=Activeer uw account
|
||||
@@ -219,8 +222,7 @@ org_still_own_repo=De organisatie heeft nog eigendomen op repositories. U moet d
|
||||
target_branch_not_exist=Doel branch bestaat niet
|
||||
|
||||
[user]
|
||||
change_avatar=Verander uw avatar op Gravatar.com
|
||||
change_custom_avatar=Wijzig uw avatar in de instellingen
|
||||
change_avatar=Change your avatar
|
||||
join_on=Aangemeld op
|
||||
repositories=repositories
|
||||
activity=Openbare activiteit
|
||||
@@ -350,6 +352,8 @@ readme_helper=Selecteer een sjabloon voor het Leesmij-bestand
|
||||
auto_init=Initialiseer deze repositorie met de geselecteerde bestanden en sjabloon
|
||||
create_repo=Nieuwe repository
|
||||
default_branch=Standaard branch
|
||||
mirror_prune=Prune
|
||||
mirror_prune_desc=Remove any remote-tracking references that no longer exist on the remote
|
||||
mirror_interval=Mirror interval(uur)
|
||||
mirror_address=Kopie-adres
|
||||
mirror_address_desc=Gelieve noodzakelijke gebruikersgegevens in de adresbalk.
|
||||
@@ -407,6 +411,7 @@ file_raw=Ruwe
|
||||
file_history=Geschiedenis
|
||||
file_view_raw=Weergave ruwe
|
||||
file_permalink=Permalink
|
||||
file_too_large=This file is too large to be shown
|
||||
|
||||
commits.commits=Commits
|
||||
commits.search=Zoeken
|
||||
@@ -469,9 +474,9 @@ issues.reopen_comment_issue=Heropen en geef commentaar
|
||||
issues.create_comment=Reageer
|
||||
issues.closed_at=`gesloten om <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`heropend om <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at='verwees naar dit probleem vanuit een commit <a id="%[1]s" href="#%[1]s"> %[2]s'</a>
|
||||
issues.commit_ref_at=`verwees naar dit probleem vanuit een commit <a id="%[1]s" href="#%[1]s"> %[2]s'</a>`
|
||||
issues.poster=Poster
|
||||
issues.collaborator=Collaborator
|
||||
issues.collaborator=Medewerker
|
||||
issues.owner=Eigenaar
|
||||
issues.sign_up_for_free=Gratis aanmelden
|
||||
issues.sign_in_require_desc=om deel te nemen in deze conversatie. Heeft u al een account? <a href="%s">Meld u aan om te reageren</a>
|
||||
@@ -501,7 +506,7 @@ pulls.nothing_to_compare=Er is niets te vergelijken omdat base en head branches
|
||||
pulls.has_pull_request=' Er is al een pull-aanvraag tussen deze twee targets: <a href="%[1]s/pulls/%[3]d"> %[2]s #% [3]d</a>'
|
||||
pulls.create=Pull verzoek aanmaken
|
||||
pulls.title_desc=wil %[1]d commits van <code>%[2]s</code> samenvoegen met <code>%[3]s</code>
|
||||
pulls.merged_title_desc=%[1] commits samengevoegd van <code>%[2]s</code> naar <code>%[3]s</code> %[4]s
|
||||
pulls.merged_title_desc=heeft %[1]d commits samengevoegd van <code>%[2]s</code> naar <code>%[3]s</code> %[4]s
|
||||
pulls.tab_conversation=Discussie
|
||||
pulls.tab_commits=Commits
|
||||
pulls.tab_files=Bestanden gewijzigd
|
||||
@@ -512,9 +517,9 @@ pulls.data_broken=Omdat informatie over de fork is verwijderd, zijn de gegevens
|
||||
pulls.is_checking=Controle van conflicten is nog bezig, ververs deze pagina in enkele ogenblikken.
|
||||
pulls.can_auto_merge_desc=Dit pull-request kan automatisch samengevoegd worden.
|
||||
pulls.cannot_auto_merge_desc=Dit pull-request kan niet worden gemerged omdat er conflicten zijn.
|
||||
pulls.cannot_auto_merge_helper=Please merge manually in order to resolve the conflicts.
|
||||
pulls.cannot_auto_merge_helper=Gelieve beide versies manueel samen te voegen om de conflicten op te lossen.
|
||||
pulls.merge_pull_request=Samenvoegen van pull verzoek
|
||||
pulls.open_unmerged_pull_exists=`You can't perform reopen operation because there is already an open pull request (#%d) from same repository with same merge information and is waiting for merging.`
|
||||
pulls.open_unmerged_pull_exists=U kan de bewerking 'heropenen' niet uitvoeren omdat er al een pull-aanvraag (#%d) is van dezelfde repository met dezelfde informatie. Voeg deze eerst samen.
|
||||
|
||||
milestones.new=Nieuwe mijlpaal
|
||||
milestones.open_tab=%d geopend
|
||||
@@ -553,7 +558,7 @@ wiki.last_commit_info=%s heeft deze pagina aangepast %s
|
||||
wiki.edit_page_button=Bewerken
|
||||
wiki.new_page_button=Nieuwe pagina
|
||||
wiki.delete_page_button=Verwijder pagina
|
||||
wiki.delete_page_notice_1=This will delete the page <code>"%s"</code>. Please be certain.
|
||||
wiki.delete_page_notice_1=Dit zal pagina <code>"%s"</code> verwijderen. Weet u het zeker?
|
||||
wiki.page_already_exists=Er bestaat al een wiki-pagina met deze naam.
|
||||
wiki.pages=Pagina’s
|
||||
wiki.last_updated=Laatst bijgewerkt: %s
|
||||
@@ -561,45 +566,50 @@ wiki.last_updated=Laatst bijgewerkt: %s
|
||||
settings=Instellingen
|
||||
settings.options=Opties
|
||||
settings.collaboration=Samenwerking
|
||||
settings.collaboration.admin=Admin
|
||||
settings.collaboration.write=Write
|
||||
settings.collaboration.read=Read
|
||||
settings.collaboration.undefined=Undefined
|
||||
settings.hooks=Webhooks
|
||||
settings.githooks=Git-hooks
|
||||
settings.basic_settings=Basis instellingen
|
||||
settings.site=Officiële site
|
||||
settings.update_settings=Instellingen bewerken
|
||||
settings.change_reponame_prompt=This change will affect how links relate to the repository.
|
||||
settings.change_reponame_prompt=Deze verandering zal gevolgen hebben voor hoe links zich verhouden tot de repository.
|
||||
settings.advanced_settings=Geavanceerde opties
|
||||
settings.wiki_desc=Enable wiki to allow people write documents
|
||||
settings.wiki_desc=Wiki inschakelen, om mensen documenten te laten schrijven
|
||||
settings.use_external_wiki=Externe wiki gebruiken
|
||||
settings.external_wiki_url=Externe wiki-URL
|
||||
settings.external_wiki_url_desc=Bezoekers worden doorgestuurd naar de URL als ze op het tabblad klikken.
|
||||
settings.issues_desc=Ingebouwde compacte issuetracker inschakelen
|
||||
settings.use_external_issue_tracker=Externe issuetracker gebruiken
|
||||
settings.tracker_url_format=URL-formaat externe issuetracker
|
||||
settings.tracker_url_format_desc=You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
|
||||
settings.pulls_desc=Enable pull requests to accept public contributions
|
||||
settings.tracker_issue_style=External Issue Tracker Naming Style:
|
||||
settings.tracker_issue_style.numeric=Numeric <span class="ui light grey text">(1234)</span>
|
||||
settings.tracker_issue_style.alphanumeric=Alphanumeric <span class="ui light grey text">(ABC-123, DEFG-234, ...)</span>
|
||||
settings.tracker_url_format_desc=U kan de aanduidingen <code>{user} {repo} {index}</code> gebruiken voor de gebruikersnaam, de naam van de repository en de lijst van open tickets.
|
||||
settings.pulls_desc=Schakel 'pull request' in om publieke bijdragen te mogelijk te maken
|
||||
settings.danger_zone=Gevaren zone
|
||||
settings.new_owner_has_same_repo=De nieuwe eigenaar heeft al een repositorie met deze naam
|
||||
settings.convert=Converteren naar gewone repository
|
||||
settings.convert_desc=U kunt deze mirror converteren naar een gewone repository. Dit kan niet ongedaan worden gemaakt.
|
||||
settings.convert_notices_1=- This operation will convert this repository mirror into a regular repository and cannot be undone.
|
||||
settings.convert_notices_1=- Deze operatie zet de mirror repository om in een gewone repository en dit kan niet ongedaan gemaakt worden.
|
||||
settings.convert_confirm=Conversie bevestigen
|
||||
settings.convert_succeed=Deze repository is geconverteerd naar een normale repository.
|
||||
settings.transfer=Eigendom overdragen
|
||||
settings.transfer_desc=Draag deze repo over aan een andere gebruiker of een organisatie waar u beheerders rechten heeft.
|
||||
settings.transfer_notices_1=- You will lose access if new owner is a individual user.
|
||||
settings.transfer_notices_2=- You will conserve access if new owner is an organization and if you're one of the owners.
|
||||
settings.transfer_form_title=Please enter following information to confirm your operation:
|
||||
settings.wiki_delete=Erase Wiki Data
|
||||
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
|
||||
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
|
||||
settings.wiki_deletion_success=Repository wiki data have been erased successfully.
|
||||
settings.transfer_notices_1=- U verliest toegang als de nieuwe gebruiker een individuele gebruiker is.
|
||||
settings.transfer_notices_2=- U behoudt toegang indien de nieuwe eigenaar een organisatie is en U één van de eigenaren van de organisatie bent.
|
||||
settings.transfer_form_title=Voer de volgende informatie in om de bewerking te bevestigen:
|
||||
settings.wiki_delete=Wiki gegevens verwijderen
|
||||
settings.wiki_delete_desc=Als U wiki informatie wist gaat deze onherroepelijk verloren. Bent U zeker?
|
||||
settings.wiki_delete_notices_1=- Deze operatie wist de wiki voor %s en schakelt de wiki uit
|
||||
settings.wiki_deletion_success=De repository met wiki data is succesvol gewist.
|
||||
settings.delete=Verwijder deze repositorie
|
||||
settings.delete_desc=Als u eenmaal een repositorie verwijderd is er geen weg terug. Gelieve zeker te zijn van uw acties.
|
||||
settings.delete_notices_1=- This operation <strong>CANNOT</strong> be undone.
|
||||
settings.delete_notices_2=- This operation will permanently delete the everything of this repository, including Git data, issues, comments and accesses of collaborators.
|
||||
settings.delete_notices_fork_1=- If this repository is public, all forks will become independent after deletion.
|
||||
settings.delete_notices_fork_2=- If this repository is private, all forks will be removed at the same time.
|
||||
settings.delete_notices_fork_3=- If you want to keep all forks after deletion, please change visibility of this repository to public first.
|
||||
settings.delete_notices_1=- Deze bewerking kan <strong>NIET</strong> ongedaan gemaakt worden.
|
||||
settings.delete_notices_2=- Deze bewerking verwijdert permanent alle informatie van deze repository met inbegrip van Git gegevens, tickets, opmerkingen en de toegang van medewerkers.
|
||||
settings.delete_notices_fork_1=- All forks will become independent after deletion.
|
||||
settings.deletion_success=Repository is succesvol verwijderd!
|
||||
settings.update_settings_success=Repositorie instellingen zijn succesvol bijgewerkt.
|
||||
settings.transfer_owner=Nieuwe eigenaar
|
||||
@@ -609,20 +619,20 @@ settings.confirm_delete=Bevestig verwijdering
|
||||
settings.add_collaborator=Nieuwe medewerker toevoegen
|
||||
settings.add_collaborator_success=medewerker is toegevoegd.
|
||||
settings.delete_collaborator=Verwijderen
|
||||
settings.collaborator_deletion=Collaborator Deletion
|
||||
settings.collaborator_deletion_desc=This user will no longer have collaboration access to this repository after deletion. Do you want to continue?
|
||||
settings.collaborator_deletion=Verwijder Medewerker
|
||||
settings.collaborator_deletion_desc=Deze gebruiker zal niet langer toegang hebben tot deze repository. Wilt U doorgaan?
|
||||
settings.remove_collaborator_success=medewerker is verwijderd.
|
||||
settings.search_user_placeholder=Zoek gebruiker...
|
||||
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
|
||||
settings.org_not_allowed_to_be_collaborator=De organisatie kan niet toegevoegd worden als medewerker.
|
||||
settings.user_is_org_member=Gebruiker is lid van de organisatie die als een medewerker kan niet worden toegevoegd.
|
||||
settings.add_webhook=Webhook toevoegen
|
||||
settings.hooks_desc=Webhooks dat de externe diensten om kennisgevingen te ontvangen wanneer bepaalde gebeurtenissen op Gogs plaatsvinden. Wanneer de opgegeven gebeurtenissen plaatsvinden, sturen we een POST-aanvraag naar elk van de URL's die u opgeeft. Meer informatie vindt u in onze <a target="_blank" href="%s"> Webhooks gids</a>.
|
||||
settings.webhook_deletion=Webhook verwijderen
|
||||
settings.webhook_deletion_desc=Delete this webhook will remove its information and all delivery history. Do you want to continue?
|
||||
settings.webhook_deletion_desc=Verwijderen van deze webhook zal de informatie en alle geschiedenis verwijderen. Wilt u doorgaan?
|
||||
settings.webhook_deletion_success=Webhook is succesvol verwijderd!
|
||||
settings.webhook.test_delivery=Test-bezorging
|
||||
settings.webhook.test_delivery_desc=Send a fake push event delivery to test your webhook settings
|
||||
settings.webhook.test_delivery_success=Test webhook has been added to delivery queue. It may take few seconds before it shows up in the delivery history.
|
||||
settings.webhook.test_delivery_desc=Stuur een nep push bericht om de webhook te testen
|
||||
settings.webhook.test_delivery_success=De test webhook is toegevoegd aan de wachtrij. Het kan enkele seconden duren voor deze in de geschiedenis wordt weergegeven.
|
||||
settings.webhook.request=Verzoek
|
||||
settings.webhook.response=Antwoord
|
||||
settings.webhook.headers=Headers
|
||||
@@ -662,7 +672,7 @@ settings.slack_domain=Slack domein
|
||||
settings.slack_channel=Slack kanaal
|
||||
settings.deploy_keys=Installeer sleutels
|
||||
settings.add_deploy_key=Toevoegen deploy sleutel
|
||||
settings.deploy_key_desc=Deploy keys have read-only access. They are not the same as personal account SSH keys.
|
||||
settings.deploy_key_desc=Sleutels voor uitrol hebben enkel leesrechten. Ze zijn niet dezelfde als de SSH sleutels van persoonlijke accounts.
|
||||
settings.no_deploy_keys=U hebt nog geen deploy sleutels toegevoegd.
|
||||
settings.title=Titel
|
||||
settings.deploy_key_content=Inhoud
|
||||
@@ -678,11 +688,13 @@ diff.parent=bovenliggende
|
||||
diff.commit=commit
|
||||
diff.data_not_available=Diff gegevens niet beschikbaar.
|
||||
diff.show_diff_stats=Toon Diff Stats
|
||||
diff.show_split_view=Split View
|
||||
diff.show_unified_view=Unified View
|
||||
diff.show_split_view=Zij-aan-zij weergave
|
||||
diff.show_unified_view=Gecombineerde weergave
|
||||
diff.stats_desc=<strong>%d gewijzigde bestanden</strong> met <strong>toevoegingen van %d</strong> en <strong>%d verwijderingen</strong>
|
||||
diff.bin=BIN
|
||||
diff.view_file=Bestand weergeven
|
||||
diff.file_suppressed=File diff suppressed because it is too large
|
||||
diff.too_many_files=Some files were not shown because too many files changed in this diff
|
||||
|
||||
release.releases=Releases
|
||||
release.new_release=Nieuwe release
|
||||
@@ -692,7 +704,7 @@ release.stable=Stabiel
|
||||
release.edit=bewerken
|
||||
release.ahead=<strong>%d</strong> aanpassingen aan %s sinds deze versie
|
||||
release.source_code=Broncode
|
||||
release.new_subheader=Publish releases to iterate product.
|
||||
release.new_subheader=Publiceer releases om te itereren.
|
||||
release.edit_subheader=Een gedetailleerd changelog helpt gebruikers te begrijpen wat er is verbeterd in deze release.
|
||||
release.tag_name=Tagnaam
|
||||
release.target=Doel
|
||||
@@ -710,7 +722,7 @@ release.save_draft=Concept opslaan
|
||||
release.edit_release=Release bewerken
|
||||
release.delete_release=Deze release verwijderen
|
||||
release.deletion=Release verwijderen
|
||||
release.deletion_desc=Deleting this release will delete the corresponding Git tag. Do you want to continue?
|
||||
release.deletion_desc=Als deze release verwijdert, worden de bijbehorende Git tag ook gewist. Wilt u doorgaan?
|
||||
release.deletion_success=Release is verwijderd!
|
||||
release.tag_name_already_exist=Versie met deze naam bestaat al.
|
||||
release.downloads=Downloads
|
||||
@@ -744,8 +756,8 @@ settings.website=Website
|
||||
settings.location=Locatie
|
||||
settings.update_settings=Instellingen bijwerken
|
||||
settings.update_setting_success=Organisatie instellingen zijn succesvol bijgewerkt.
|
||||
settings.change_orgname_prompt=This change will affect how links relate to the organization.
|
||||
settings.update_avatar_success=Organization avatar setting has been updated successfully.
|
||||
settings.change_orgname_prompt=Deze verandering beinvloed de verhouding tussen links en de organisatie.
|
||||
settings.update_avatar_success=Organisatie avatar-instellingen zijn succesvol gewijzigd.
|
||||
settings.delete=Verwijder organisatie
|
||||
settings.delete_account=Verwijder deze organisatie
|
||||
settings.delete_prompt=Deze actie zal de origanisatie permanent verwijderen. U kunt dit <strong>NIET</strong> terug draaien!
|
||||
@@ -754,7 +766,7 @@ settings.delete_org_title=Verwijderen organsiatie
|
||||
settings.delete_org_desc=Deze organisatie zal permanent worden verwijderd, wilt u doorgaan?
|
||||
settings.hooks_desc=Een webhook toevoegen die door <strong>alle repositories</strong> in deze organisatie getriggerd kan worden.
|
||||
|
||||
members.membership_visibility=Membership Visibility:
|
||||
members.membership_visibility=Zichtbaarheid lidmaatschap:
|
||||
members.public=Openbaar
|
||||
members.public_helper=maak prive
|
||||
members.private=Prive
|
||||
@@ -764,7 +776,7 @@ members.owner=Eigenaar
|
||||
members.member=Lid
|
||||
members.remove=Verwijderen
|
||||
members.leave=Verlaat
|
||||
members.invite_desc=Add a new member to %s:
|
||||
members.invite_desc=Voeg nieuw lid toe aan %s:
|
||||
members.invite_now=Nu uitnodigen
|
||||
|
||||
teams.join=Lid worden
|
||||
@@ -820,16 +832,16 @@ dashboard.delete_inactivate_accounts=Verwijder alle inactieve accounts
|
||||
dashboard.delete_inactivate_accounts_success=Alle inactivering van rekeningen hebben verwijderd.
|
||||
dashboard.delete_repo_archives=Verwijderen van alle repositories archieven
|
||||
dashboard.delete_repo_archives_success=Alle repositories archieven hebben verwijderd.
|
||||
dashboard.delete_missing_repos=Delete all repository records that lost Git files
|
||||
dashboard.delete_missing_repos_success=All repository records that lost Git files have been deleted successfully.
|
||||
dashboard.delete_missing_repos=Verwijder alle repositories zonder Git files
|
||||
dashboard.delete_missing_repos_success=Alle repositories zonder Git files verwijderd.
|
||||
dashboard.git_gc_repos=Garbage collectie uitvoeren
|
||||
dashboard.git_gc_repos_success=Garbage collectie met succes uitgevoerd.
|
||||
dashboard.resync_all_sshkeys=Herschrijf '.ssh/authorized_keys' (Let op: alle sleutels die niet van Gogs zijn zullen verloren gaan!)
|
||||
dashboard.resync_all_sshkeys_success=Alle publieke sleutels zijn herschreven.
|
||||
dashboard.resync_all_update_hooks=Herschrijf alle repositorie-hooks (nodig als de configuratie bestandslocatie is gewijzigd)
|
||||
dashboard.resync_all_update_hooks_success=Alle repositorie-hooks zijn herschreven.
|
||||
dashboard.reinit_missing_repos=Reinitialize all repository records that lost Git files
|
||||
dashboard.reinit_missing_repos_success=All repository records that lost Git files have been reinitialized successfully.
|
||||
dashboard.reinit_missing_repos=Alle repositories zonder Git files opnieuw initialiseren
|
||||
dashboard.reinit_missing_repos_success=Alle repositories zonder Git files zijn succesvol opnieuw geinitializeerd.
|
||||
|
||||
dashboard.server_uptime=Uptime server
|
||||
dashboard.current_goroutine=Huidige Goroutines
|
||||
@@ -874,12 +886,13 @@ users.edit=Bewerken
|
||||
users.auth_source=Authenticatiebron
|
||||
users.local=Lokaal
|
||||
users.auth_login_name=Authenticatie-loginnaam
|
||||
users.password_helper=Leave it empty to remain unchanged.
|
||||
users.password_helper=Laat leeg om ongewijzigd te blijven.
|
||||
users.update_profile_success=Profiel is succesvol bijgewerkt.
|
||||
users.edit_account=Bewerk account
|
||||
users.max_repo_creation=Maximum Repository Creation Limit
|
||||
users.max_repo_creation_desc=(Set -1 to use global default limit)
|
||||
users.max_repo_creation=Maximum-limiet voor aanmaken van repositories
|
||||
users.max_repo_creation_desc=(Zet op -1 om de globale limiet te gebruiken)
|
||||
users.is_activated=Dit account is geactiveerd
|
||||
users.prohibit_login=This account is prohibited to login
|
||||
users.is_admin=Dit account heeft beheerdersrechten
|
||||
users.allow_git_hook=Deze account beschikt over machtigingen voor het maken van Git haken
|
||||
users.allow_import_local=Dit account mag lokale repositories importeren
|
||||
@@ -902,7 +915,7 @@ repos.watches=Volgers
|
||||
repos.stars=Sterren
|
||||
repos.issues=Kwesties
|
||||
|
||||
auths.auth_manage_panel=Authentication Manage Panel
|
||||
auths.auth_manage_panel=Authenticatie-beheer paneel
|
||||
auths.new=Nieuwe bron toevoegen
|
||||
auths.name=Naam
|
||||
auths.type=Type
|
||||
@@ -910,20 +923,21 @@ auths.enabled=Ingeschakeld
|
||||
auths.updated=Bijgewerkt
|
||||
auths.auth_type=Authenticatietype
|
||||
auths.auth_name=Authenticatienaam
|
||||
auths.security_protocol=Security Protocol
|
||||
auths.domain=Domein
|
||||
auths.host=Host
|
||||
auths.port=Poort
|
||||
auths.bind_dn=Binden DN
|
||||
auths.bind_password=Bind Password
|
||||
auths.bind_password_helper=Warning: This password is stored in plain text. Do not use a high privileged account.
|
||||
auths.bind_password=Bind wachtwoord
|
||||
auths.bind_password_helper=Opgelet: Dit wachtwoord wordt opgeslagen als leesbare tekst. Gebruik geen account met verhoogde rechten.
|
||||
auths.user_base=User Search Base
|
||||
auths.user_dn=User DN
|
||||
auths.attribute_username=Username attribute
|
||||
auths.attribute_username_placeholder=Leave empty to use sign-in form field value for user name.
|
||||
auths.attribute_username=Gebruikersnaam attribuut
|
||||
auths.attribute_username_placeholder=Laat leeg om het login veld van het formulier te gebruiken als gebruikersnaam.
|
||||
auths.attribute_name=Voornaam attribuut
|
||||
auths.attribute_surname=Achternaam attribuut
|
||||
auths.attribute_mail=E-mail attribuut
|
||||
auths.attributes_in_bind=Fetch attributes in Bind DN context
|
||||
auths.attributes_in_bind=Verkrijg attributes van de Bind DN context
|
||||
auths.filter=Gebruikersfilter
|
||||
auths.admin_filter=Beheerdersfilter
|
||||
auths.ms_ad_sa=MS Ad SA
|
||||
@@ -931,20 +945,20 @@ auths.smtp_auth=SMTP-authenticatietype
|
||||
auths.smtphost=SMTP host
|
||||
auths.smtpport=SMTP poort
|
||||
auths.allowed_domains=Toegelaten domeinen
|
||||
auths.allowed_domains_helper=Leave it empty to not restrict any domains. Multiple domains should be separated by comma ','.
|
||||
auths.allowed_domains_helper=Laat dit leeg om geen enkel domein te beperken. Meerdere domeinen moeten door een komma (',') gescheiden worden.
|
||||
auths.enable_tls=Activeer TLS-encryptie
|
||||
auths.skip_tls_verify=TLS-verificatie overslaan
|
||||
auths.pam_service_name=PAM servicenaam
|
||||
auths.enable_auto_register=Activeer automatische registratie
|
||||
auths.tips=Tips
|
||||
auths.edit=Edit Authentication Setting
|
||||
auths.edit=Verificatie-instelling bewerken
|
||||
auths.activated=Deze autorisatiemethode is geactiveerd
|
||||
auths.new_success=New authentication '%s' has been added successfully.
|
||||
auths.update_success=Authentication setting has been updated successfully.
|
||||
auths.new_success=Nieuwe authenticatie '%s' werd toegevoegd.
|
||||
auths.update_success=Authenticatie instellingen zijn succesvol gewijzigd.
|
||||
auths.update=Authenticatie-instellingen bijwerken
|
||||
auths.delete=Deze authenticatiewijze verwijderen
|
||||
auths.delete_auth_title=Authentication Deletion
|
||||
auths.delete_auth_desc=This authentication is going to be deleted, do you want to continue?
|
||||
auths.delete_auth_title=Authenticatie verwijderd
|
||||
auths.delete_auth_desc=Deze authenticatie zal verwijderd worden, wil je verdergaan?
|
||||
auths.still_in_used=This authentication is still used by some users, please delete or convert these users to another login type first.
|
||||
auths.deletion_success=Authentication has been deleted successfully!
|
||||
|
||||
@@ -1040,13 +1054,13 @@ monitor.start=Starttijd
|
||||
monitor.execute_time=Uitvoertijd
|
||||
|
||||
notices.system_notice_list=Systeem aankondigingen
|
||||
notices.view_detail_header=View Notice Detail
|
||||
notices.view_detail_header=Bekijk bericht details
|
||||
notices.actions=Acties
|
||||
notices.select_all=Alles selecteren
|
||||
notices.deselect_all=Alles deselecteren
|
||||
notices.inverse_selection=Selectie omkeren
|
||||
notices.delete_selected=Selectie verwijderen
|
||||
notices.delete_all=Delete All Notices
|
||||
notices.delete_all=Verwijder alle berichten
|
||||
notices.type=Type
|
||||
notices.type_1=Opslagplaats
|
||||
notices.desc=Beschrijving
|
||||
|
||||
24
conf/locale/locale_pl-PL.ini
Executable file → Normal file
24
conf/locale/locale_pl-PL.ini
Executable file → Normal file
@@ -148,6 +148,8 @@ forget_password=Zapomniałeś hasła?
|
||||
sign_up_now=Potrzebujesz konta? Zarejestruj się teraz.
|
||||
confirmation_mail_sent_prompt=Nowa wiadomość e-mail z potwierdzeniem została wysłana do <b>%s</b>, proszę sprawdzić swoją skrzynkę odbiorczą w ciągu najbliższych godzin %d aby dokończyć proces rejestracji.
|
||||
active_your_account=Aktywuj swoje konto
|
||||
prohibit_login=Login Prohibited
|
||||
prohibit_login_desc=Your account is prohibited to login, please contact site admin.
|
||||
resent_limit_prompt=Niestety, zbyt często wysyłasz e-mail aktywacyjny. Proszę odczekać 3 minuty.
|
||||
has_unconfirmed_mail=Witaj, %s, masz niepotwierdzony adres e-mail (<b>%s</b>). Jeśli nie otrzymałeś wiadomości e-mail z potwierdzeniem lub potrzebujesz wysłać nową, kliknij na poniższy przycisk.
|
||||
resend_mail=Kliknij tutaj, aby wysłać e-mail aktywacyjny
|
||||
@@ -157,6 +159,7 @@ reset_password=Resetowanie hasła
|
||||
invalid_code=Niestety, Twój kod potwierdzający wygasł lub jest nieprawidłowy.
|
||||
reset_password_helper=Kliknij tutaj, aby zresetować hasło
|
||||
password_too_short=Długość hasła nie może być mniejsza niż 6 znaków.
|
||||
non_local_account=Non-local accounts cannot change passwords through Gogs.
|
||||
|
||||
[mail]
|
||||
activate_account=Prosimy aktywować swoje konto
|
||||
@@ -219,8 +222,7 @@ org_still_own_repo=Ta organizacja dalej jest właścicielem repozytorium, które
|
||||
target_branch_not_exist=Gałąź docelowa nie istnieje.
|
||||
|
||||
[user]
|
||||
change_avatar=Zmień swój avatar na gravatar.com
|
||||
change_custom_avatar=Zmień awatar w ustawieniach
|
||||
change_avatar=Change your avatar
|
||||
join_on=Dołączył
|
||||
repositories=Repozytoria
|
||||
activity=Publiczna aktywność
|
||||
@@ -350,6 +352,8 @@ readme_helper=Wybierz szablon readme
|
||||
auto_init=Zainicjuj to repozytorium używając wybranych plików i szablonu
|
||||
create_repo=Utwórz repozytorium
|
||||
default_branch=Domyślna gałąź
|
||||
mirror_prune=Prune
|
||||
mirror_prune_desc=Remove any remote-tracking references that no longer exist on the remote
|
||||
mirror_interval=Częstotliwość kopiowania (godziny)
|
||||
mirror_address=Adres kopii lustrzanej
|
||||
mirror_address_desc=Proszę podać wymagane poświadczenia użytkownika w adresie.
|
||||
@@ -407,6 +411,7 @@ file_raw=Czysty
|
||||
file_history=Historia
|
||||
file_view_raw=Zobacz czysty
|
||||
file_permalink=Bezpośredni odnośnik
|
||||
file_too_large=This file is too large to be shown
|
||||
|
||||
commits.commits=Commity
|
||||
commits.search=Przeszukaj commity
|
||||
@@ -561,6 +566,10 @@ wiki.last_updated=Ostatnia aktualizacja %s
|
||||
settings=Ustawienia
|
||||
settings.options=Opcje
|
||||
settings.collaboration=Współpraca
|
||||
settings.collaboration.admin=Admin
|
||||
settings.collaboration.write=Write
|
||||
settings.collaboration.read=Read
|
||||
settings.collaboration.undefined=Undefined
|
||||
settings.hooks=Webhooki
|
||||
settings.githooks=Hooki Git
|
||||
settings.basic_settings=Ustawienia podstawowe
|
||||
@@ -575,6 +584,9 @@ settings.external_wiki_url_desc=Odwiedzający zostaną przekierowani do adresu U
|
||||
settings.issues_desc=Włącz wbudowany lekki system zgłaszania problemów
|
||||
settings.use_external_issue_tracker=Użyj zewnętrznego systemu zgłaszania problemów
|
||||
settings.tracker_url_format=Format dla adresu URL zewnętrznego systemu
|
||||
settings.tracker_issue_style=External Issue Tracker Naming Style:
|
||||
settings.tracker_issue_style.numeric=Numeric <span class="ui light grey text">(1234)</span>
|
||||
settings.tracker_issue_style.alphanumeric=Alphanumeric <span class="ui light grey text">(ABC-123, DEFG-234, ...)</span>
|
||||
settings.tracker_url_format_desc=Symbole zastępcze <code>{user} {repo} {index}</code> mogą być użyte dla nazwy użytkownika, nazwy repozytorium i numeru problemu.
|
||||
settings.pulls_desc=Włącz obsługę pull request, aby akceptować publiczny wkład
|
||||
settings.danger_zone=Strefa niebezpieczeństwa
|
||||
@@ -597,9 +609,7 @@ settings.delete=Usuń to repozytorium
|
||||
settings.delete_desc=Po usunięciu repozytorium nie ma odwrotu. Upewnij się, że tego chcesz.
|
||||
settings.delete_notices_1=- Ta operacja <strong>NIE MOŻE</strong> zostać cofnięta.
|
||||
settings.delete_notices_2=- Ta operacja trwale usunie wszystko z tego repozytorium, w tym dane Git, problemy, komentarze i dostęp dla współpracowników.
|
||||
settings.delete_notices_fork_1=- Jeśli to repozytorium jest publiczne, wszystkie forki staną się niezależne.
|
||||
settings.delete_notices_fork_2=- Jeśli to repozytorium jest prywatne, forki zostaną usunięte wraz z usunięciem tego repozytorium.
|
||||
settings.delete_notices_fork_3=- Jeśli chcesz zachować wszystkie forki po usunięciu, proszę najpierw uczyń to repozytorium publicznym.
|
||||
settings.delete_notices_fork_1=- All forks will become independent after deletion.
|
||||
settings.deletion_success=Repozytorium zostało pomyślnie usunięte!
|
||||
settings.update_settings_success=Opcje repozytorium zostały pomyślnie zaktualizowane.
|
||||
settings.transfer_owner=Nowy właściciel
|
||||
@@ -683,6 +693,8 @@ diff.show_unified_view=Zunifikowany widok
|
||||
diff.stats_desc=<strong>%d zmienionych plików</strong> z <strong>%d dodań</strong> i <strong>%d usunięć</strong>
|
||||
diff.bin=BIN
|
||||
diff.view_file=Wyświetl plik
|
||||
diff.file_suppressed=File diff suppressed because it is too large
|
||||
diff.too_many_files=Some files were not shown because too many files changed in this diff
|
||||
|
||||
release.releases=Wydania
|
||||
release.new_release=Nowe wydanie
|
||||
@@ -880,6 +892,7 @@ users.edit_account=Edytuj konto
|
||||
users.max_repo_creation=Maksymalna liczba repozytoriów
|
||||
users.max_repo_creation_desc=(Ustaw -1, aby użyć globalnego limitu)
|
||||
users.is_activated=To konto jest aktywne
|
||||
users.prohibit_login=This account is prohibited to login
|
||||
users.is_admin=To konto ma uprawnienia administratora
|
||||
users.allow_git_hook=To konto posiada uprawnienia do tworzenia hooków Git
|
||||
users.allow_import_local=To konto ma uprawnienia do importu lokalnych repozytoriów
|
||||
@@ -910,6 +923,7 @@ auths.enabled=Włączono
|
||||
auths.updated=Zaktualizowano
|
||||
auths.auth_type=Typ uwierzytelniania
|
||||
auths.auth_name=Nazwa uwierzytelniania
|
||||
auths.security_protocol=Security Protocol
|
||||
auths.domain=Domena
|
||||
auths.host=Host
|
||||
auths.port=Port
|
||||
|
||||
26
conf/locale/locale_pt-BR.ini
Executable file → Normal file
26
conf/locale/locale_pt-BR.ini
Executable file → Normal file
@@ -11,7 +11,7 @@ register=Registrar
|
||||
website=Site
|
||||
version=Versão
|
||||
page=Página
|
||||
template=Modelo
|
||||
template=Template
|
||||
language=Idioma
|
||||
create_new=Criar...
|
||||
user_profile_and_more=Perfil do usuário e configurações
|
||||
@@ -148,6 +148,8 @@ forget_password=Esqueceu a senha?
|
||||
sign_up_now=Precisa de uma conta? Cadastre-se agora.
|
||||
confirmation_mail_sent_prompt=Um novo e-mail de confirmação foi enviado para <b>%s</b>, por favor, verifique sua caixa de entrada nas próximas %d horas para completar seu registro.
|
||||
active_your_account=Ativar Sua Conta
|
||||
prohibit_login=Login Prohibited
|
||||
prohibit_login_desc=Your account is prohibited to login, please contact site admin.
|
||||
resent_limit_prompt=Desculpe, você está enviando um e-mail de ativação com muita frequência. Por favor, aguarde 3 minutos.
|
||||
has_unconfirmed_mail=Oi %s, você possui um endereço de e-mail não confirmado (<b>%s</b>). Se você não recebeu um e-mail de confirmação ou precisa reenviar um novo, clique no botão abaixo.
|
||||
resend_mail=Clique aqui para reenviar seu e-mail de ativação
|
||||
@@ -157,6 +159,7 @@ reset_password=Redefinir Sua Senha
|
||||
invalid_code=Desculpe, seu código de confirmação expirou ou não é válido.
|
||||
reset_password_helper=Clique aqui para redefinir sua senha
|
||||
password_too_short=O comprimento da senha não pode ser menor que 6.
|
||||
non_local_account=Não é possível mudar a senha de contas não-locais pelo Gogs.
|
||||
|
||||
[mail]
|
||||
activate_account=Por favor, ative sua conta
|
||||
@@ -219,8 +222,7 @@ org_still_own_repo=Esta organização ainda tem a propriedade do repositório, v
|
||||
target_branch_not_exist=O branch de destino não existe.
|
||||
|
||||
[user]
|
||||
change_avatar=Altere o seu avatar em gravatar.com
|
||||
change_custom_avatar=Altere seu avatar nas configurações
|
||||
change_avatar=Mude seu avatar
|
||||
join_on=Inscreveu-se em
|
||||
repositories=Repositórios
|
||||
activity=Atividade Pública
|
||||
@@ -350,6 +352,8 @@ readme_helper=Selecione um modelo de leia-me
|
||||
auto_init=Inicializar este repositório com os arquivos selecionados e modelo
|
||||
create_repo=Criar Repositório
|
||||
default_branch=Branch padrão
|
||||
mirror_prune=Varrer
|
||||
mirror_prune_desc=Remova quaisquer referências que não existem mais no remote
|
||||
mirror_interval=Intervalo de Espelho (hora)
|
||||
mirror_address=Endereço do espelho
|
||||
mirror_address_desc=Por favor, inclua as credenciais do usuário necessários no endereço.
|
||||
@@ -407,6 +411,7 @@ file_raw=Cru
|
||||
file_history=Histórico
|
||||
file_view_raw=Ver cru
|
||||
file_permalink=Link permanente
|
||||
file_too_large=This file is too large to be shown
|
||||
|
||||
commits.commits=Commits
|
||||
commits.search=Pesquisar commits
|
||||
@@ -561,6 +566,10 @@ wiki.last_updated=Última atualização %s
|
||||
settings=Configurações
|
||||
settings.options=Opções
|
||||
settings.collaboration=Colaboração
|
||||
settings.collaboration.admin=Administrador
|
||||
settings.collaboration.write=Escrita
|
||||
settings.collaboration.read=Leitura
|
||||
settings.collaboration.undefined=Indefinido
|
||||
settings.hooks=Webhooks
|
||||
settings.githooks=Hooks do Git
|
||||
settings.basic_settings=Configurações Básicas
|
||||
@@ -575,6 +584,9 @@ settings.external_wiki_url_desc=Os visitantes serão redirecionados para a URL q
|
||||
settings.issues_desc=Habilitar gerenciamento de "problemas" nativo
|
||||
settings.use_external_issue_tracker=Usar issue tracker externo
|
||||
settings.tracker_url_format=Formato de URL do issue tracker externo
|
||||
settings.tracker_issue_style=Estilo de nome de issue tracker externo:
|
||||
settings.tracker_issue_style.numeric=Numérico <span class="ui light grey text">(1234)</span>
|
||||
settings.tracker_issue_style.alphanumeric=Alfanumérico <span class="ui light grey text">(ABC-123, DEFG-234, ...)</span>
|
||||
settings.tracker_url_format_desc=Você pode usar o espaço reservado <code>{user} {repo} {index}</code> para o nome do usuário, índice de nome e a questão do repositório.
|
||||
settings.pulls_desc=Habilitar pull requests para aceitar contribuições públicas
|
||||
settings.danger_zone=Zona de Perigo
|
||||
@@ -597,9 +609,7 @@ settings.delete=Deletar Este Repositório
|
||||
settings.delete_desc=Uma vez que você deleta um repositório, não tem volta. Por favor, tenha certeza.
|
||||
settings.delete_notices_1=-Esta operação <strong>NÃO PODERÁ</strong> ser desfeita.
|
||||
settings.delete_notices_2=- Esta operação irá apagar permanentemente o tudo deste repositório, incluindo os dados do Git, problemas, comentários e acessos dos colaboradores.
|
||||
settings.delete_notices_fork_1=- Se este repositório é público, todos os forks se tornarão independentes após a deleção.
|
||||
settings.delete_notices_fork_2=- Se este repositório é privado, todos os forks serão removidos imediatamente.
|
||||
settings.delete_notices_fork_3=- Se você deseja manter todos os forks, por favor muda a visibilidade do repositório para pública primeiro.
|
||||
settings.delete_notices_fork_1=-Todos os forks se tornarão independentes após a exclusão.
|
||||
settings.deletion_success=Repositório excluído com sucesso!
|
||||
settings.update_settings_success=As opções do repositório foram atualizadas com sucesso.
|
||||
settings.transfer_owner=Novo Dono
|
||||
@@ -683,6 +693,8 @@ diff.show_unified_view=Visão unificada
|
||||
diff.stats_desc=<strong> %d arquivos alterados</strong> com <strong>%d adições</strong> e <strong>%d exclusões</strong>
|
||||
diff.bin=BIN
|
||||
diff.view_file=Ver Arquivo
|
||||
diff.file_suppressed=File diff suppressed because it is too large
|
||||
diff.too_many_files=Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff
|
||||
|
||||
release.releases=Versões
|
||||
release.new_release=Nova Versão
|
||||
@@ -880,6 +892,7 @@ users.edit_account=Editar Conta
|
||||
users.max_repo_creation=Limite máximo de criação de repositórios
|
||||
users.max_repo_creation_desc=(Use "-1" para utilizar o limite padrão)
|
||||
users.is_activated=Esta conta está ativada
|
||||
users.prohibit_login=This account is prohibited to login
|
||||
users.is_admin=Esta conta tem permissões de administrador
|
||||
users.allow_git_hook=Esta conta tem permissões para criar hooks do Git
|
||||
users.allow_import_local=Esta conta tem permissões para importar repositórios locais
|
||||
@@ -910,6 +923,7 @@ auths.enabled=Habilitado
|
||||
auths.updated=Atualizado
|
||||
auths.auth_type=Tipo de autenticação
|
||||
auths.auth_name=Nome da autenticação
|
||||
auths.security_protocol=Protocolo de segurança
|
||||
auths.domain=Domínio
|
||||
auths.host=Host
|
||||
auths.port=Porta
|
||||
|
||||
26
conf/locale/locale_ru-RU.ini
Executable file → Normal file
26
conf/locale/locale_ru-RU.ini
Executable file → Normal file
@@ -148,6 +148,8 @@ forget_password=Забыли пароль?
|
||||
sign_up_now=Нужен аккаунт? Зарегистрируйтесь.
|
||||
confirmation_mail_sent_prompt=Новое письмо для подтверждения было направлено на <b>%s</b>, пожалуйста, проверьте ваш почтовый ящик в течение %d часов для завершения регистрации.
|
||||
active_your_account=Активируйте свой аккаунт
|
||||
prohibit_login=Login Prohibited
|
||||
prohibit_login_desc=Your account is prohibited to login, please contact site admin.
|
||||
resent_limit_prompt=Извините, вы уже запросили активацию по электронной почте недавно. Пожалуйста, подождите 3 минуты, а затем повторите попытку.
|
||||
has_unconfirmed_mail=Здравствуйте, %s! У вас есть неподтвержденный адрес электронной почты (<b>%s</b>). Если вам не приходило письмо с подтверждением или нужно выслать новое письмо, нажмите на кнопку ниже.
|
||||
resend_mail=Нажмите здесь, чтобы переотправить активационное письмо
|
||||
@@ -157,6 +159,7 @@ reset_password=Сброс пароля
|
||||
invalid_code=Извините, ваш код подтверждения истек или не является допустимым.
|
||||
reset_password_helper=Нажмите здесь, чтобы сбросить свой пароль
|
||||
password_too_short=Длина пароля не менее 6 символов.
|
||||
non_local_account=Нелокальные аккаунты не могут изменить пароль через Gogs.
|
||||
|
||||
[mail]
|
||||
activate_account=Пожалуйста активируйте свой аккаунт
|
||||
@@ -219,8 +222,7 @@ org_still_own_repo=Данная организация все еще являе
|
||||
target_branch_not_exist=Целевая ветка не существует
|
||||
|
||||
[user]
|
||||
change_avatar=Измените ваш аватар на gravatar.com
|
||||
change_custom_avatar=Измените ваш аватар в настройках
|
||||
change_avatar=Изменить аватар
|
||||
join_on=Присоединился
|
||||
repositories=Репозитории
|
||||
activity=Активность
|
||||
@@ -350,6 +352,8 @@ readme_helper=Выберите шаблон для файла readme
|
||||
auto_init=Инициализировать этот репозиторий выбранными файлами и шаблоном
|
||||
create_repo=Создать репозиторий
|
||||
default_branch=Ветка по умолчанию
|
||||
mirror_prune=Очистить
|
||||
mirror_prune_desc=Remove any remote-tracking references that no longer exist on the remote
|
||||
mirror_interval=Интервал зеркалирования (час)
|
||||
mirror_address=Адрес зеркала
|
||||
mirror_address_desc=Укажите необходимые учетные данные в адрес.
|
||||
@@ -407,6 +411,7 @@ file_raw=Исходник
|
||||
file_history=История
|
||||
file_view_raw=Посмотреть исходник
|
||||
file_permalink=Постоянная ссылка
|
||||
file_too_large=This file is too large to be shown
|
||||
|
||||
commits.commits=Коммиты
|
||||
commits.search=Поиск коммитов
|
||||
@@ -561,6 +566,10 @@ wiki.last_updated=Последнее обновление %s
|
||||
settings=Настройки
|
||||
settings.options=Опции
|
||||
settings.collaboration=Сотрудничество
|
||||
settings.collaboration.admin=Администратор
|
||||
settings.collaboration.write=Запись
|
||||
settings.collaboration.read=Просмотр
|
||||
settings.collaboration.undefined=Не определено
|
||||
settings.hooks=Автоматическое обновление
|
||||
settings.githooks=Git хуки
|
||||
settings.basic_settings=Основные параметры
|
||||
@@ -575,6 +584,9 @@ settings.external_wiki_url_desc=Посетители будут перенапр
|
||||
settings.issues_desc=Включить встроенную, легковесную систему отслеживания ошибок
|
||||
settings.use_external_issue_tracker=Использовать внешнюю систему отслеживания ошибок
|
||||
settings.tracker_url_format=Внешний формат ссылки системы отслеживания ошибок.
|
||||
settings.tracker_issue_style=Стиль Именования Внешней Системы Учета Задач:
|
||||
settings.tracker_issue_style.numeric=Числовой <span class="ui light grey text"> (1234)</span>
|
||||
settings.tracker_issue_style.alphanumeric=Буквенно-цифровой <span class="ui light grey text"> (ABC-123, DEF-234,...)</span>
|
||||
settings.tracker_url_format_desc=Вы можете использовать шаблон <code>{user} {repo} {index}</code> для имени пользователя, репозитория и номера задачи.
|
||||
settings.pulls_desc=Включить публичные запросы на слияние
|
||||
settings.danger_zone=Опасная зона
|
||||
@@ -597,9 +609,7 @@ settings.delete=Удалить этот репозиторий
|
||||
settings.delete_desc=Будьте внимательны! Как только вы удалите репозиторий — пути назад не будет.
|
||||
settings.delete_notices_1=- Эта операция <strong>НЕ МОЖЕТ</strong> быть отменена.
|
||||
settings.delete_notices_2=- Эта операция навсегда удалит всё из этого репозитория, включая данные Git, связанные с ним задачи, комментарии и права доступа для сотрудников.
|
||||
settings.delete_notices_fork_1=- Если данный репозиторий является публичным, все склонированные репозитории останутся независимыми, после его удаления.
|
||||
settings.delete_notices_fork_2=- Если данный репозиторий является приватным, все его ответвления будут удалены вместе с ним.
|
||||
settings.delete_notices_fork_3=- Если вы хотите сохранить все ответвления после удаления репозитория, то сначала сделайте его публичным.
|
||||
settings.delete_notices_fork_1=- Все отвлетвления станут независимыми после удаления.
|
||||
settings.deletion_success=Репозиторий был успешно удалён!
|
||||
settings.update_settings_success=Настройка репозитория обновлена успешно.
|
||||
settings.transfer_owner=Новый владелец
|
||||
@@ -676,13 +686,15 @@ settings.deploy_key_deletion_success=Ключ развертывания усп
|
||||
diff.browse_source=Просмотр исходного кода
|
||||
diff.parent=Родитель
|
||||
diff.commit=Сommit
|
||||
diff.data_not_available=Данные Diff не доступны.
|
||||
diff.data_not_available=Данные Diff недоступны.
|
||||
diff.show_diff_stats=Показать статистику Diff
|
||||
diff.show_split_view=Разделённый вид
|
||||
diff.show_unified_view=Единый вид
|
||||
diff.stats_desc=<strong> %d измененных файлов</strong> с <strong>%d добавлено</strong> и <strong>%d удалено</strong>
|
||||
diff.bin=BIN
|
||||
diff.view_file=Просмотреть файл
|
||||
diff.file_suppressed=File diff suppressed because it is too large
|
||||
diff.too_many_files=Некоторые файлы не были показать из-за большого количества измененных файлов
|
||||
|
||||
release.releases=Релизы
|
||||
release.new_release=Новый релиз
|
||||
@@ -880,6 +892,7 @@ users.edit_account=Изменение учетной записи
|
||||
users.max_repo_creation=Ограничение максимального количества создаваемых репозиториев
|
||||
users.max_repo_creation_desc=(Установить -1 для использования стандартного глобального значения предела)
|
||||
users.is_activated=Эта учетная запись активирована
|
||||
users.prohibit_login=This account is prohibited to login
|
||||
users.is_admin=У этой учетной записи есть права администратора
|
||||
users.allow_git_hook=Пользователь имеет право создать Git перехватчик
|
||||
users.allow_import_local=Пользователь имеет право импортировать локальные репозитории
|
||||
@@ -910,6 +923,7 @@ auths.enabled=Включено
|
||||
auths.updated=Обновлено
|
||||
auths.auth_type=Тип аутентификации
|
||||
auths.auth_name=Имя аутентификации
|
||||
auths.security_protocol=Протокол безопасности
|
||||
auths.domain=Домен
|
||||
auths.host=Хост
|
||||
auths.port=Порт
|
||||
|
||||
1112
conf/locale/locale_tr-TR.ini
Normal file
1112
conf/locale/locale_tr-TR.ini
Normal file
File diff suppressed because it is too large
Load Diff
24
conf/locale/locale_zh-CN.ini
Executable file → Normal file
24
conf/locale/locale_zh-CN.ini
Executable file → Normal file
@@ -148,6 +148,8 @@ forget_password=忘记密码?
|
||||
sign_up_now=还没帐户?马上注册。
|
||||
confirmation_mail_sent_prompt=一封新的确认邮件已经被发送至 <b>%s</b>,请检查您的收件箱并在 %d 小时内完成确认注册操作。
|
||||
active_your_account=激活您的帐户
|
||||
prohibit_login=禁止登录
|
||||
prohibit_login_desc=您的帐户被禁止登录,请联系网站管理员。
|
||||
resent_limit_prompt=对不起,您请求发送激活邮件过于频繁,请等待 3 分钟后再试!
|
||||
has_unconfirmed_mail=%s 您好,系统检测到您有一封发送至 <b>%s</b> 但未被确认的邮件。如果您未收到激活邮件,或需要重新发送,请单击下方的按钮。
|
||||
resend_mail=单击此处重新发送确认邮件
|
||||
@@ -157,6 +159,7 @@ reset_password=重置密码
|
||||
invalid_code=对不起,您的确认代码已过期或已失效。
|
||||
reset_password_helper=单击此处重置密码
|
||||
password_too_short=密码长度不能少于 6 位!
|
||||
non_local_account=非本地类型的帐户无法通过 Gogs 修改密码。
|
||||
|
||||
[mail]
|
||||
activate_account=请激活您的帐户
|
||||
@@ -219,8 +222,7 @@ org_still_own_repo=该组织仍然是某些仓库的拥有者,您必须先转
|
||||
target_branch_not_exist=目标分支不存在。
|
||||
|
||||
[user]
|
||||
change_avatar=到 gravatar.com 上修改您的头像
|
||||
change_custom_avatar=到个人设置中修改头像
|
||||
change_avatar=修改头像
|
||||
join_on=加入于
|
||||
repositories=仓库列表
|
||||
activity=公开活动
|
||||
@@ -350,6 +352,8 @@ readme_helper=请选择自述文档模板
|
||||
auto_init=使用选定的文件和模板初始化仓库
|
||||
create_repo=创建仓库
|
||||
default_branch=默认分支
|
||||
mirror_prune=修剪
|
||||
mirror_prune_desc=当远程追踪的引用被删除时本地也同步删除
|
||||
mirror_interval=镜像同步周期(小时)
|
||||
mirror_address=镜像地址
|
||||
mirror_address_desc=请在镜像地址中写入必要的用户凭据信息。
|
||||
@@ -407,6 +411,7 @@ file_raw=原始文件
|
||||
file_history=文件历史
|
||||
file_view_raw=查看原始文件
|
||||
file_permalink=永久链接
|
||||
file_too_large=文件过大导致无法显示
|
||||
|
||||
commits.commits=次代码提交
|
||||
commits.search=搜索提交历史
|
||||
@@ -561,6 +566,10 @@ wiki.last_updated=最后更新于 %s
|
||||
settings=仓库设置
|
||||
settings.options=基本设置
|
||||
settings.collaboration=管理协作者
|
||||
settings.collaboration.admin=管理权限
|
||||
settings.collaboration.write=可写权限
|
||||
settings.collaboration.read=可读权限
|
||||
settings.collaboration.undefined=未定义
|
||||
settings.hooks=管理 Web 钩子
|
||||
settings.githooks=管理 Git 钩子
|
||||
settings.basic_settings=基本设置
|
||||
@@ -575,6 +584,9 @@ settings.external_wiki_url_desc=当访问者单击分页标签时,将会被重
|
||||
settings.issues_desc=启用内置的轻量级工单管理系统
|
||||
settings.use_external_issue_tracker=使用外部的工单管理系统
|
||||
settings.tracker_url_format=外部工单管理系统的 URL 格式
|
||||
settings.tracker_issue_style=外部工单管理系统命名风格:
|
||||
settings.tracker_issue_style.numeric=纯数字 <span class="ui light grey text">(1234)</span>
|
||||
settings.tracker_issue_style.alphanumeric=字母和数字结合 <span class="ui light grey text">(ABC-123, DEFG-234, ...)</span>
|
||||
settings.tracker_url_format_desc=您可以使用 <code>{user} {repo} {index}</code> 分别作为用户名、仓库名和工单索引的占位符。
|
||||
settings.pulls_desc=启用合并请求以接受社区贡献
|
||||
settings.danger_zone=危险操作区
|
||||
@@ -597,9 +609,7 @@ settings.delete=删除本仓库
|
||||
settings.delete_desc=删除仓库操作不可逆转,请三思而后行。
|
||||
settings.delete_notices_1=- 此操作 <strong>不可以</strong> 被回滚。
|
||||
settings.delete_notices_2=- 此操作将永久删除该仓库,包括 Git 数据、 工单、 评论和协作者的操作权限。
|
||||
settings.delete_notices_fork_1=- 如果该仓库为公开的,则在删除仓库后所有的派生仓库都将转换成独立的仓库。
|
||||
settings.delete_notices_fork_2=- 如果该仓库为私有,则会同时删除所有的派生仓库。
|
||||
settings.delete_notices_fork_3=- 如果您想要保留派生仓库,请先将可见性修改为公开的后再进行删除操作。
|
||||
settings.delete_notices_fork_1=- 删除完成后所有的派生仓库都将转换为独立的仓库。
|
||||
settings.deletion_success=仓库删除成功!
|
||||
settings.update_settings_success=仓库设置更新成功!
|
||||
settings.transfer_owner=新拥有者
|
||||
@@ -683,6 +693,8 @@ diff.show_unified_view=合并视图
|
||||
diff.stats_desc=共有 <strong> %d 个文件被更改</strong>,包括 <strong>%d 次插入</strong> 和 <strong>%d 次删除</strong>
|
||||
diff.bin=二进制
|
||||
diff.view_file=查看文件
|
||||
diff.file_suppressed=文件差异内容过多而无法显示
|
||||
diff.too_many_files=部分文件因为文件数量过多而无法显示
|
||||
|
||||
release.releases=版本发布
|
||||
release.new_release=发布新版
|
||||
@@ -880,6 +892,7 @@ users.edit_account=编辑用户信息
|
||||
users.max_repo_creation=最大允许创建仓库数量
|
||||
users.max_repo_creation_desc=(设置为 -1 表示使用全局默认值)
|
||||
users.is_activated=该用户已被激活
|
||||
users.prohibit_login=该帐户被禁止登录
|
||||
users.is_admin=该用户具有管理员权限
|
||||
users.allow_git_hook=该用户具有创建 Git 钩子的权限
|
||||
users.allow_import_local=该用户具有导入本地仓库的权限
|
||||
@@ -910,6 +923,7 @@ auths.enabled=已启用
|
||||
auths.updated=最后更新时间
|
||||
auths.auth_type=认证类型
|
||||
auths.auth_name=认证名称
|
||||
auths.security_protocol=安全协议
|
||||
auths.domain=域名
|
||||
auths.host=主机地址
|
||||
auths.port=主机端口
|
||||
|
||||
86
conf/locale/locale_zh-HK.ini
Executable file → Normal file
86
conf/locale/locale_zh-HK.ini
Executable file → Normal file
@@ -38,7 +38,7 @@ settings=設定
|
||||
your_profile=個人資料
|
||||
your_settings=用戶設定
|
||||
|
||||
activities=Activities
|
||||
activities=活動
|
||||
pull_requests=合併請求
|
||||
issues=問題
|
||||
|
||||
@@ -58,7 +58,7 @@ db_name=資料庫名稱
|
||||
db_helper=如果您使用 MySQL,請使用 INNODB 引擎以及 utf8_general_ci 字符集。
|
||||
ssl_mode=SSL 模式
|
||||
path=數據庫文件路徑
|
||||
sqlite_helper=The file path of SQLite3 or TiDB database. <br>Please use absolute path when you start as service.
|
||||
sqlite_helper=SQLite3 或 TiDB 資料庫檔案路徑。<br>作為以服務執行時,請使用絕對路徑。
|
||||
err_empty_db_path=SQLite3 或 TiDB 的數據庫路徑不能為空。
|
||||
err_invalid_tidb_name=TiDB 數據庫名稱不允許包含字符 "." 或 "-" 。
|
||||
no_admin_and_disable_registration=您不能夠在未創建管理員用戶的情況下禁止註冊。
|
||||
@@ -79,8 +79,8 @@ http_port=HTTP 端口號
|
||||
http_port_helper=應用監聽的端口號
|
||||
app_url=應用程式網址
|
||||
app_url_helper=該設置影響 HTTP/HTTPS 複製地址和一些郵箱中的連結。
|
||||
log_root_path=Log Path
|
||||
log_root_path_helper=Directory to write log files to.
|
||||
log_root_path=日誌路徑
|
||||
log_root_path_helper=寫入日誌檔目錄
|
||||
|
||||
optional_title=可選設置
|
||||
email_title=電子郵件服務設定
|
||||
@@ -117,7 +117,7 @@ run_user_not_match=執行系統用戶非當前用戶:%s -> %s
|
||||
save_config_failed=應用配置保存失敗:%v
|
||||
invalid_admin_setting=管理員帳戶設置不正確:%v
|
||||
install_success=您好!我們很高興您選擇使用 Gogs,祝您使用愉快,代碼從此無 BUG!
|
||||
invalid_log_root_path=Log root path is invalid: %v
|
||||
invalid_log_root_path=日誌根目錄無效: %v
|
||||
|
||||
[home]
|
||||
uname_holder=用戶名或郵箱
|
||||
@@ -133,8 +133,8 @@ issues.in_your_repos=屬於該用戶倉庫的
|
||||
|
||||
[explore]
|
||||
repos=探索倉庫
|
||||
users=Users
|
||||
search=Search
|
||||
users=用戶
|
||||
search=搜索
|
||||
|
||||
[auth]
|
||||
create_new_account=創建帳戶
|
||||
@@ -148,6 +148,8 @@ forget_password=忘記密碼?
|
||||
sign_up_now=還沒帳戶?馬上註冊。
|
||||
confirmation_mail_sent_prompt=一封新的確認郵件已經被發送至 <b>%s</b>,請檢查您的收件箱並在 %d 小時內完成確認註冊操作。
|
||||
active_your_account=激活您的帳戶
|
||||
prohibit_login=Login Prohibited
|
||||
prohibit_login_desc=Your account is prohibited to login, please contact site admin.
|
||||
resent_limit_prompt=對不起,您請求發送激活郵件過於頻繁,請等待 3 分鐘後再試!
|
||||
has_unconfirmed_mail=%s 您好,您有一封發送至( <b>%s</b>) 但未被確認的郵件。如果您未收到激活郵件,或需要重新發送,請單擊下方的按鈕。
|
||||
resend_mail=單擊此處重新發送確認郵件
|
||||
@@ -157,6 +159,7 @@ reset_password=重置密碼
|
||||
invalid_code=對不起,您的確認代碼已過期或已失效。
|
||||
reset_password_helper=單擊此處重置密碼
|
||||
password_too_short=密碼長度不能少於 6 位!
|
||||
non_local_account=Non-local accounts cannot change passwords through Gogs.
|
||||
|
||||
[mail]
|
||||
activate_account=請激活您的帳戶
|
||||
@@ -219,8 +222,7 @@ org_still_own_repo=該組織仍然是某些倉庫的擁有者,您必須先轉
|
||||
target_branch_not_exist=目標分支不存在
|
||||
|
||||
[user]
|
||||
change_avatar=到 gravatar.com 上修改您的頭像
|
||||
change_custom_avatar=到個人設置中修改頭像
|
||||
change_avatar=Change your avatar
|
||||
join_on=加入於
|
||||
repositories=倉庫列表
|
||||
activity=公開活動
|
||||
@@ -259,7 +261,7 @@ cancel=取消操作
|
||||
enable_custom_avatar=啟動自定義頭像
|
||||
choose_new_avatar=選擇新的頭像
|
||||
update_avatar=更新頭像設置
|
||||
delete_current_avatar=Delete Current Avatar
|
||||
delete_current_avatar=刪除當前頭像
|
||||
uploaded_avatar_not_a_image=上傳的文件不是一張圖片!
|
||||
update_avatar_success=您的頭像設置更新成功!
|
||||
|
||||
@@ -350,6 +352,8 @@ readme_helper=請選擇readme模板
|
||||
auto_init=使用選定的文件和模板初始化倉庫
|
||||
create_repo=創建倉庫
|
||||
default_branch=默認分支
|
||||
mirror_prune=Prune
|
||||
mirror_prune_desc=Remove any remote-tracking references that no longer exist on the remote
|
||||
mirror_interval=鏡像同步周期(小時)
|
||||
mirror_address=鏡像地址
|
||||
mirror_address_desc=請在位址中包括必要的使用者憑據。
|
||||
@@ -382,7 +386,7 @@ unwatch=取消關注
|
||||
watch=關註
|
||||
unstar=取消讚好
|
||||
star=讚好
|
||||
fork=派生
|
||||
fork=複刻
|
||||
|
||||
no_desc=暫無描述
|
||||
quick_guide=快速幫助
|
||||
@@ -407,6 +411,7 @@ file_raw=原始文件
|
||||
file_history=文件歷史
|
||||
file_view_raw=查看原始文件
|
||||
file_permalink=永久連結
|
||||
file_too_large=This file is too large to be shown
|
||||
|
||||
commits.commits=次代碼提交
|
||||
commits.search=搜索提交歷史
|
||||
@@ -471,7 +476,7 @@ issues.closed_at=`於 <a id="%[1]s" href="#%[1]s">%[2]s</a> 關閉`
|
||||
issues.reopened_at=`於 <a id="%[1]s" href="#%[1]s">%[2]s</a> 重新開啟`
|
||||
issues.commit_ref_at=`在代碼提交 <a id="%[1]s" href="#%[1]s">%[2]s</a> 中引用了該問題`
|
||||
issues.poster=發佈者
|
||||
issues.collaborator=Collaborator
|
||||
issues.collaborator=協同者
|
||||
issues.owner=所有者
|
||||
issues.sign_up_for_free=免費註冊
|
||||
issues.sign_in_require_desc=及加入到對話當中。如果您已經註冊,可以直接 <a href="%s">登錄及評論</a>
|
||||
@@ -488,7 +493,7 @@ issues.label_modify=修改標籤
|
||||
issues.label_deletion=刪除標籤
|
||||
issues.label_deletion_desc=刪除該標籤將會移除所有問題中相關的訊息。是否繼續?
|
||||
issues.label_deletion_success=標籤刪除成功!
|
||||
issues.num_participants=%d Participants
|
||||
issues.num_participants=%d 參與者
|
||||
|
||||
pulls.new=創建合併請求
|
||||
pulls.compare_changes=對比文件變化
|
||||
@@ -552,8 +557,8 @@ wiki.save_page=保存頁面
|
||||
wiki.last_commit_info=%s 於 %s 修改了此頁面
|
||||
wiki.edit_page_button=修改
|
||||
wiki.new_page_button=新的頁面
|
||||
wiki.delete_page_button=Delete Page
|
||||
wiki.delete_page_notice_1=This will delete the page <code>"%s"</code>. Please be certain.
|
||||
wiki.delete_page_button=刪除頁面
|
||||
wiki.delete_page_notice_1=這將刪除頁面 <code>"%s"</code>。請三思而後行。
|
||||
wiki.page_already_exists=相同名稱的 Wiki 頁面已經存在。
|
||||
wiki.pages=所有頁面
|
||||
wiki.last_updated=最後更新於 %s
|
||||
@@ -561,6 +566,10 @@ wiki.last_updated=最後更新於 %s
|
||||
settings=倉庫設置
|
||||
settings.options=基本設置
|
||||
settings.collaboration=管理協作者
|
||||
settings.collaboration.admin=Admin
|
||||
settings.collaboration.write=Write
|
||||
settings.collaboration.read=Read
|
||||
settings.collaboration.undefined=Undefined
|
||||
settings.hooks=管理 Web 鉤子
|
||||
settings.githooks=管理 Git 鉤子
|
||||
settings.basic_settings=基本設置
|
||||
@@ -575,12 +584,15 @@ settings.external_wiki_url_desc=當分頁上按一下,訪客將會重新導到
|
||||
settings.issues_desc=啟用內置的輕量級問題管理系統
|
||||
settings.use_external_issue_tracker=使用外部的問題管理系統
|
||||
settings.tracker_url_format=外部問題管理系統的 URL 格式
|
||||
settings.tracker_issue_style=External Issue Tracker Naming Style:
|
||||
settings.tracker_issue_style.numeric=Numeric <span class="ui light grey text">(1234)</span>
|
||||
settings.tracker_issue_style.alphanumeric=Alphanumeric <span class="ui light grey text">(ABC-123, DEFG-234, ...)</span>
|
||||
settings.tracker_url_format_desc=您可以使用 <code>{user} {repo} {index}</code> 分別作為用戶名、倉庫名和問題索引的占位符。
|
||||
settings.pulls_desc=啟用合併請求以接受社區貢獻
|
||||
settings.danger_zone=危險操作區
|
||||
settings.new_owner_has_same_repo=新的倉庫擁有者已經存在同名倉庫!
|
||||
settings.convert=Convert To Regular Repository
|
||||
settings.convert_desc=You can convert this mirror to a regular repository. This cannot be reversed.
|
||||
settings.convert=轉換為正規倉庫
|
||||
settings.convert_desc=您可以將此鏡像轉成正規倉庫。此動做不可逆。
|
||||
settings.convert_notices_1=- This operation will convert this repository mirror into a regular repository and cannot be undone.
|
||||
settings.convert_confirm=Confirm Conversion
|
||||
settings.convert_succeed=Repository has been converted to regular type successfully.
|
||||
@@ -589,17 +601,15 @@ settings.transfer_desc=您可以將倉庫轉移至您擁有管理員權限的帳
|
||||
settings.transfer_notices_1=- 如果您將倉庫轉移給個人用戶,您將會丟失操作權限。
|
||||
settings.transfer_notices_2=- 如果您將倉庫轉移給您是所有者的組織,您的操作權限將被保留。
|
||||
settings.transfer_form_title=請輸入以下信息以確認您的操作:
|
||||
settings.wiki_delete=Erase Wiki Data
|
||||
settings.wiki_delete=刪除 Wiki 資料
|
||||
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
|
||||
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
|
||||
settings.wiki_delete_notices_1=- 將刪除和停用 %s 的 wiki
|
||||
settings.wiki_deletion_success=Repository wiki data have been erased successfully.
|
||||
settings.delete=刪除本倉庫
|
||||
settings.delete_desc=刪除倉庫操作不可逆轉,請三思而後行。
|
||||
settings.delete_notices_1=- 此操作 <strong>不可以</strong> 被回滾。
|
||||
settings.delete_notices_2=- 此操作將永久刪除該倉庫,包括 Git 數據、 問題、 評論和協作者的操作權限。
|
||||
settings.delete_notices_fork_1=- 如果該倉庫為公開的,則在刪除倉庫後所有的派生倉庫都將轉換成獨立的倉庫。
|
||||
settings.delete_notices_fork_2=- 如果該倉庫為私有,則會同時刪除所有的派生倉庫。
|
||||
settings.delete_notices_fork_3=- 如果您想要保留派生倉庫,請先將可見性修改為公開的後再進行刪除操作。
|
||||
settings.delete_notices_fork_1=- All forks will become independent after deletion.
|
||||
settings.deletion_success=倉庫刪除成功!
|
||||
settings.update_settings_success=倉庫設置更新成功!
|
||||
settings.transfer_owner=新擁有者
|
||||
@@ -608,7 +618,7 @@ settings.transfer_succeed=倉庫所有權轉移成功!
|
||||
settings.confirm_delete=確認刪除倉庫
|
||||
settings.add_collaborator=增加新的協作者
|
||||
settings.add_collaborator_success=成功添加新的協作者!
|
||||
settings.delete_collaborator=Delete
|
||||
settings.delete_collaborator=刪除
|
||||
settings.collaborator_deletion=Collaborator Deletion
|
||||
settings.collaborator_deletion_desc=This user will no longer have collaboration access to this repository after deletion. Do you want to continue?
|
||||
settings.remove_collaborator_success=被操作的協作者已經被收回權限!
|
||||
@@ -683,6 +693,8 @@ diff.show_unified_view=統一視圖
|
||||
diff.stats_desc=共有 <strong> %d 個文件被更改</strong>,包括 <strong>%d 次插入</strong> 和 <strong>%d 次删除</strong>
|
||||
diff.bin=二進制
|
||||
diff.view_file=查看文件
|
||||
diff.file_suppressed=File diff suppressed because it is too large
|
||||
diff.too_many_files=Some files were not shown because too many files changed in this diff
|
||||
|
||||
release.releases=版本發佈
|
||||
release.new_release=發佈新版本
|
||||
@@ -880,6 +892,7 @@ users.edit_account=編輯用戶信息
|
||||
users.max_repo_creation=最大儲存庫新增限制
|
||||
users.max_repo_creation_desc=(設定 -1 使用全域預設限制)
|
||||
users.is_activated=該用戶已被激活
|
||||
users.prohibit_login=This account is prohibited to login
|
||||
users.is_admin=該用戶具有管理員權限
|
||||
users.allow_git_hook=該帳戶具有創建 Git 鉤子的權限
|
||||
users.allow_import_local=該用戶具有導入本地倉庫的權限
|
||||
@@ -910,6 +923,7 @@ auths.enabled=已啟用
|
||||
auths.updated=最後更新時間
|
||||
auths.auth_type=認證類型
|
||||
auths.auth_name=認證名稱
|
||||
auths.security_protocol=Security Protocol
|
||||
auths.domain=域名
|
||||
auths.host=主機地址
|
||||
auths.port=主機端口
|
||||
@@ -963,17 +977,17 @@ config.log_file_root_path=日志文件根目錄
|
||||
config.script_type=腳本類型
|
||||
config.reverse_auth_user=反向代理認證
|
||||
|
||||
config.ssh_config=SSH Configuration
|
||||
config.ssh_enabled=Enabled
|
||||
config.ssh_start_builtin_server=Start Builtin Server
|
||||
config.ssh_config=SSH 配置
|
||||
config.ssh_enabled=已啟用
|
||||
config.ssh_start_builtin_server=啟動內建伺服器
|
||||
config.ssh_domain=Domain
|
||||
config.ssh_port=Port
|
||||
config.ssh_listen_port=Listen Port
|
||||
config.ssh_root_path=Root Path
|
||||
config.ssh_key_test_path=Key Test Path
|
||||
config.ssh_keygen_path=Keygen ('ssh-keygen') Path
|
||||
config.ssh_minimum_key_size_check=Minimum Key Size Check
|
||||
config.ssh_minimum_key_sizes=Minimum Key Sizes
|
||||
config.ssh_port=埠
|
||||
config.ssh_listen_port=監聽埠
|
||||
config.ssh_root_path=根路徑
|
||||
config.ssh_key_test_path=金鑰測試路徑
|
||||
config.ssh_keygen_path=金鑰產生 (' ssh-keygen ') 路徑
|
||||
config.ssh_minimum_key_size_check=金鑰最小大小檢查
|
||||
config.ssh_minimum_key_sizes=金鑰最小大小
|
||||
|
||||
config.db_config=數據庫配置
|
||||
config.db_type=數據庫類型
|
||||
@@ -1004,9 +1018,9 @@ config.mailer_disable_helo=禁用 HELO 操作
|
||||
config.mailer_name=發送者名稱
|
||||
config.mailer_host=郵件主機地址
|
||||
config.mailer_user=發送者帳號
|
||||
config.send_test_mail=Send Test Email
|
||||
config.test_mail_failed=Fail to send test email to '%s': %v
|
||||
config.test_mail_sent=Test email has been sent to '%s'.
|
||||
config.send_test_mail=發送測試郵件
|
||||
config.test_mail_failed=無法向 '%s' 發送測試郵件: %v
|
||||
config.test_mail_sent=測試電子郵件已發送到 '%s'。
|
||||
config.oauth_config=社交帳號配置
|
||||
config.oauth_enabled=啟用服務
|
||||
config.cache_config=Cache 配置
|
||||
|
||||
1112
conf/locale/locale_zh-TW.ini
Normal file
1112
conf/locale/locale_zh-TW.ini
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
# Docker for Gogs
|
||||
|
||||
Visit [Docker Hub](https://hub.docker.com/r/gogs/gogs/) see all available tags.
|
||||
Visit [Docker Hub](https://hub.docker.com/r/gogs/) see all available images and tags.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -43,9 +43,11 @@ If you're more comfortable with mounting data to a data container, the commands
|
||||
```
|
||||
# Create data container
|
||||
docker run --name=gogs-data --entrypoint /bin/true gogs/gogs
|
||||
|
||||
# Use `docker run` for the first time.
|
||||
docker run --name=gogs --volumes-from gogs-data -p 10022:22 -p 10080:3000 gogs/gogs
|
||||
```
|
||||
|
||||
#### Using Docker 1.9 Volume command
|
||||
|
||||
```
|
||||
@@ -71,9 +73,27 @@ Most of settings are obvious and easy to understand, but there are some settings
|
||||
|
||||
Full documentation of application settings can be found [here](http://gogs.io/docs/advanced/configuration_cheat_sheet.html).
|
||||
|
||||
### Crond
|
||||
### Container options
|
||||
|
||||
Please set environment variable `RUN_CROND` to be `true` or `1` in order to start `crond` inside the container.
|
||||
This container have some options available via environment variables, these options are opt-in features that can help the administration of this container:
|
||||
|
||||
- **SOCAT_LINK**:
|
||||
- <u>Possible value:</u>
|
||||
`true`, `false`, `1`, `0`
|
||||
- <u>Default:</u>
|
||||
`true`
|
||||
- <u>Action:</u>
|
||||
Bind linked docker container to localhost socket using socat.
|
||||
Any exported port from a linked container will be binded to the matching port on localhost.
|
||||
- <u>Disclaimer:</u>
|
||||
As this option rely on the environment variable created by docker when a container is linked, this option should be deactivated in managed environment such as Rancher or Kubernetes (set to `0` or `false`)
|
||||
- **RUN_CROND**:
|
||||
- <u>Possible value:</u>
|
||||
`true`, `false`, `1`, `0`
|
||||
- <u>Default:</u>
|
||||
`false`
|
||||
- <u>Action:</u>
|
||||
Request crond to be run inside the container. Its default configuration will periodically run all scripts from `/etc/periodic/${period}` but custom crontabs can be added to `/var/spool/cron/crontabs/`.
|
||||
|
||||
## Upgrade
|
||||
|
||||
|
||||
@@ -5,19 +5,28 @@ set -e
|
||||
# Set temp environment vars
|
||||
export GOPATH=/tmp/go
|
||||
export PATH=${PATH}:${GOPATH}/bin
|
||||
export GO15VENDOREXPERIMENT=1
|
||||
|
||||
# Install build deps
|
||||
apk --no-cache --no-progress add --virtual build-deps linux-pam-dev go gcc musl-dev
|
||||
apk --no-cache --no-progress add --virtual build-deps build-base linux-pam-dev go
|
||||
|
||||
# Init go environment to build Gogs
|
||||
# Install glide
|
||||
git clone -b 0.10.2 https://github.com/Masterminds/glide ${GOPATH}/src/github.com/Masterminds/glide
|
||||
cd ${GOPATH}/src/github.com/Masterminds/glide
|
||||
make build
|
||||
go install
|
||||
|
||||
|
||||
|
||||
# Build Gogs
|
||||
mkdir -p ${GOPATH}/src/github.com/gogits/
|
||||
ln -s /app/gogs/ ${GOPATH}/src/github.com/gogits/gogs
|
||||
cd ${GOPATH}/src/github.com/gogits/gogs
|
||||
go get -v -tags "sqlite cert pam"
|
||||
go build -tags "sqlite cert pam"
|
||||
glide install
|
||||
make build TAGS="sqlite cert pam"
|
||||
|
||||
# Cleanup GOPATH
|
||||
rm -r $GOPATH
|
||||
# Cleanup GOPATH & vendoring dir
|
||||
rm -r $GOPATH /app/gogs/vendor
|
||||
|
||||
# Remove build deps
|
||||
apk --no-progress del build-deps
|
||||
|
||||
60
glide.lock
generated
60
glide.lock
generated
@@ -1,14 +1,14 @@
|
||||
hash: f2fa73b9a379e1fa12f2b48fb0b9942a545b4518a2d71cbd956ee81093347773
|
||||
updated: 2016-03-19T14:44:26.835671547-04:00
|
||||
hash: 1d5fcf2a90f7621ecbc0b1abed548e11d13bda3fea49b4326c829a523268e5cf
|
||||
updated: 2016-06-12T17:35:14.27036884+08:00
|
||||
imports:
|
||||
- name: github.com/bradfitz/gomemcache
|
||||
version: fb1f79c6b65acda83063cbc69f6bba1522558bfc
|
||||
subpackages:
|
||||
- memcache
|
||||
- name: github.com/codegangsta/cli
|
||||
version: aca5b047ed14d17224157c3434ea93bf6cdaadee
|
||||
version: 1efa31f08b9333f1bd4882d61f9d668a70cd902e
|
||||
- name: github.com/go-macaron/binding
|
||||
version: a68f34212fe257219981e43adfe4c96ab48f42cd
|
||||
version: 9440f336b443056c90d7d448a0a55ad8c7599880
|
||||
- name: github.com/go-macaron/cache
|
||||
version: 56173531277692bc2925924d51fda1cd0a6b8178
|
||||
subpackages:
|
||||
@@ -21,7 +21,7 @@ imports:
|
||||
- name: github.com/go-macaron/gzip
|
||||
version: cad1c6580a07c56f5f6bc52d66002a05985c5854
|
||||
- name: github.com/go-macaron/i18n
|
||||
version: d2d3329f13b52314f3292c4cecb601fad13f02c8
|
||||
version: ef57533c3b0fc2d8581deda14937e52f11a203ab
|
||||
- name: github.com/go-macaron/inject
|
||||
version: c5ab7bf3a307593cd44cb272d1a5beea473dd072
|
||||
- name: github.com/go-macaron/session
|
||||
@@ -31,25 +31,27 @@ imports:
|
||||
- name: github.com/go-macaron/toolbox
|
||||
version: 82b511550b0aefc36b3a28062ad3a52e812bee38
|
||||
- name: github.com/go-sql-driver/mysql
|
||||
version: 66312f7fe2678aa0f5ec770f96702f4c4ec5aa8e
|
||||
version: 3654d25ec346ee8ce71a68431025458d52a38ac0
|
||||
- name: github.com/go-xorm/core
|
||||
version: 502158401cde814951eae62f064d9e5ff39e13ce
|
||||
version: bc1b7f81f0e369289078424064634a5ee7d21051
|
||||
- name: github.com/go-xorm/xorm
|
||||
version: 769f6b3ae663248e8f1b1d8fecbe1eb26ac77ac7
|
||||
version: b8b1711cde4d9c68da95cd0ff8de0de0cb491df3
|
||||
- name: github.com/gogits/chardet
|
||||
version: 2404f777256163ea3eadb273dada5dcb037993c0
|
||||
- name: github.com/gogits/cron
|
||||
version: 3abc0f88f2062336bcc41b43a4febbd847a390ce
|
||||
version: 96040e4fab17baa0391ce571694e4ccb5fce5dac
|
||||
- name: github.com/gogits/git-module
|
||||
version: 76e8cce6c7ef3ba1cf75752261c721ebf14cd129
|
||||
version: 53bcb7352ff838610c537c9b589ca79bca92c661
|
||||
- name: github.com/gogits/go-gogs-client
|
||||
version: 788ec59749df076b98e208909b44fdef02779deb
|
||||
version: ee68cd9eefff11615f336e9965762f6736eeecc8
|
||||
- name: github.com/issue9/identicon
|
||||
version: f8c0d2ce04db79c663b1da33d3a9f62be753ee88
|
||||
version: d36b54562f4cf70c83653e13dc95c220c79ef521
|
||||
- name: github.com/jaytaylor/html2text
|
||||
version: 52d9b785554a1918cb09909b89a1509a98b853fd
|
||||
- name: github.com/kardianos/minwinsvc
|
||||
version: cad6b2b879b0970e4245a20ebf1a81a756e2bb70
|
||||
- name: github.com/klauspost/compress
|
||||
version: 006acde2c5d283d2f8b8aa03d8f0cd2891c680cf
|
||||
version: 14eb9c4951195779ecfbec34431a976de7335b0a
|
||||
subpackages:
|
||||
- gzip
|
||||
- flate
|
||||
@@ -58,11 +60,11 @@ imports:
|
||||
- name: github.com/klauspost/crc32
|
||||
version: 19b0b332c9e4516a6370a0456e6182c3b5036720
|
||||
- name: github.com/lib/pq
|
||||
version: 165a3529e799da61ab10faed1fabff3662d6193f
|
||||
version: ee1442bda7bd1b6a84e913bdb421cb1874ec629d
|
||||
subpackages:
|
||||
- oid
|
||||
- name: github.com/mattn/go-sqlite3
|
||||
version: 76e335f60bbcee20755df9864f0153af1a80ad2d
|
||||
version: 38ee283dabf11c9cbdb968eebd79b1fa7acbabe6
|
||||
- name: github.com/mcuadros/go-version
|
||||
version: d52711f8d6bea8dc01efafdb68ad95a4e2606630
|
||||
- name: github.com/microcosm-cc/bluemonday
|
||||
@@ -72,9 +74,9 @@ imports:
|
||||
- name: github.com/nfnt/resize
|
||||
version: 4d93a29130b1b6aba503e2aa8b50f516213ea80e
|
||||
- name: github.com/russross/blackfriday
|
||||
version: b43df972fb5fdf3af8d2e90f38a69d374fe26dd0
|
||||
version: 4e6f303e8d936855981ddcdbfc092b03d2b2b68e
|
||||
- name: github.com/satori/go.uuid
|
||||
version: e673fdd4dea8a7334adbbe7f57b7e4b00bdc5502
|
||||
version: 879c5887cd475cd7864858769793b2ceb0d44feb
|
||||
- name: github.com/sergi/go-diff
|
||||
version: ec7fdbb58eb3e300c8595ad5ac74a5aa50019cc7
|
||||
subpackages:
|
||||
@@ -88,32 +90,36 @@ imports:
|
||||
- name: github.com/Unknwon/com
|
||||
version: 28b053d5a2923b87ce8c5a08f3af779894a72758
|
||||
- name: github.com/Unknwon/i18n
|
||||
version: 3b48b6662051bed72d36efa3c1e897bdf96b2e37
|
||||
version: 39d6f2727e0698b1021ceb6a77c1801aa92e7d5d
|
||||
- name: github.com/Unknwon/paginater
|
||||
version: 7748a72e01415173a27d79866b984328e7b0c12b
|
||||
- name: golang.org/x/crypto
|
||||
version: c197bcf24cde29d3f73c7b4ac6fd41f4384e8af6
|
||||
version: 77f4136a99ffb5ecdbdd0226bd5cb146cf56bc0e
|
||||
subpackages:
|
||||
- ssh
|
||||
- curve25519
|
||||
- ed25519
|
||||
- ed25519/internal/edwards25519
|
||||
- name: golang.org/x/net
|
||||
version: 35b06af0720201bc2f326773a80767387544f8c4
|
||||
version: 3f122ce3dbbe488b7e6a8bdb26f41edec852a40b
|
||||
subpackages:
|
||||
- html
|
||||
- html/charset
|
||||
- html/atom
|
||||
- name: golang.org/x/sys
|
||||
version: 9d4e42a20653790449273b3c85e67d6d8bae6e2e
|
||||
version: 7f918dd405547ecb864d14a8ecbbfe205b5f930f
|
||||
subpackages:
|
||||
- windows/svc
|
||||
- windows
|
||||
- name: golang.org/x/text
|
||||
version: 1b466db55e0ba5d56ef5315c728216b42f796491
|
||||
version: e4775119bd79944a15a741ac4be61e43509a70d9
|
||||
subpackages:
|
||||
- transform
|
||||
- language
|
||||
- encoding
|
||||
- encoding/charmap
|
||||
- encoding/htmlindex
|
||||
- internal/tag
|
||||
- encoding/internal/identifier
|
||||
- encoding/internal
|
||||
- encoding/japanese
|
||||
@@ -121,10 +127,8 @@ imports:
|
||||
- encoding/simplifiedchinese
|
||||
- encoding/traditionalchinese
|
||||
- encoding/unicode
|
||||
- language
|
||||
- internal/utf8internal
|
||||
- runes
|
||||
- internal/tag
|
||||
- name: gopkg.in/alexcesaro/quotedprintable.v3
|
||||
version: 2caba252f4dc53eaf6b553000885530023f54623
|
||||
- name: gopkg.in/asn1-ber.v1
|
||||
@@ -132,13 +136,13 @@ imports:
|
||||
- name: gopkg.in/bufio.v1
|
||||
version: 567b2bfa514e796916c4747494d6ff5132a1dfce
|
||||
- name: gopkg.in/gomail.v2
|
||||
version: 060a5f4e98dbf37408cf0c745681e4001d877827
|
||||
version: 81ebce5c23dfd25c6c67194b37d3dd3f338c98b1
|
||||
- name: gopkg.in/ini.v1
|
||||
version: 776aa739ce9373377cd16f526cdf06cb4c89b40f
|
||||
version: 72ba3e6b9e6b87e0c74c9a7a4dc86e8dd8ba4355
|
||||
- name: gopkg.in/ldap.v2
|
||||
version: 07a7330929b9ee80495c88a4439657d89c7dbd87
|
||||
version: 0e7db8eb77695b5a952f0e5d78df9ab160050c73
|
||||
- name: gopkg.in/macaron.v1
|
||||
version: 94a5ef7105036242f79e5e07a8eb8651d06c8533
|
||||
version: 2133042f8d1022b8253e4e23f7940467941409ce
|
||||
- name: gopkg.in/redis.v2
|
||||
version: e6179049628164864e6e84e973cfb56335748dea
|
||||
devImports: []
|
||||
|
||||
@@ -50,6 +50,7 @@ import:
|
||||
- package: golang.org/x/text
|
||||
subpackages:
|
||||
- transform
|
||||
- language
|
||||
- package: gopkg.in/gomail.v2
|
||||
- package: gopkg.in/ini.v1
|
||||
- package: gopkg.in/ldap.v2
|
||||
|
||||
2
gogs.go
2
gogs.go
@@ -17,7 +17,7 @@ import (
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const APP_VER = "0.9.13.0318"
|
||||
const APP_VER = "0.9.48.0722"
|
||||
|
||||
func init() {
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
|
||||
@@ -20,6 +20,33 @@ const (
|
||||
ACCESS_MODE_OWNER // 4
|
||||
)
|
||||
|
||||
func (mode AccessMode) String() string {
|
||||
switch mode {
|
||||
case ACCESS_MODE_READ:
|
||||
return "read"
|
||||
case ACCESS_MODE_WRITE:
|
||||
return "write"
|
||||
case ACCESS_MODE_ADMIN:
|
||||
return "admin"
|
||||
case ACCESS_MODE_OWNER:
|
||||
return "owner"
|
||||
default:
|
||||
return "none"
|
||||
}
|
||||
}
|
||||
|
||||
// ParseAccessMode returns corresponding access mode to given permission string.
|
||||
func ParseAccessMode(permission string) AccessMode {
|
||||
switch permission {
|
||||
case "write":
|
||||
return ACCESS_MODE_WRITE
|
||||
case "admin":
|
||||
return ACCESS_MODE_ADMIN
|
||||
default:
|
||||
return ACCESS_MODE_READ
|
||||
}
|
||||
}
|
||||
|
||||
// Access represents the highest access level of a user to the repository. The only access type
|
||||
// that is not in this table is the real owner of a repository. In case of an organization
|
||||
// repository, the members of the owners team are in this table.
|
||||
|
||||
@@ -489,7 +489,7 @@ func CommitRepoAction(
|
||||
Content: string(bs),
|
||||
RepoID: repo.ID,
|
||||
RepoUserName: repoUserName,
|
||||
RepoName: repoName,
|
||||
RepoName: repo.Name,
|
||||
RefName: refName,
|
||||
IsPrivate: repo.IsPrivate,
|
||||
}); err != nil {
|
||||
@@ -517,7 +517,7 @@ func CommitRepoAction(
|
||||
Before: oldCommitID,
|
||||
After: newCommitID,
|
||||
CompareUrl: setting.AppUrl + commit.CompareUrl,
|
||||
Commits: commit.ToApiPayloadCommits(repo.FullRepoLink()),
|
||||
Commits: commit.ToApiPayloadCommits(repo.FullLink()),
|
||||
Repo: payloadRepo,
|
||||
Pusher: &api.PayloadAuthor{
|
||||
Name: pusher_name,
|
||||
@@ -561,7 +561,7 @@ func transferRepoAction(e Engine, actUser, oldOwner, newOwner *User, repo *Repos
|
||||
RepoUserName: newOwner.Name,
|
||||
RepoName: repo.Name,
|
||||
IsPrivate: repo.IsPrivate,
|
||||
Content: path.Join(oldOwner.LowerName, repo.LowerName),
|
||||
Content: path.Join(oldOwner.Name, repo.Name),
|
||||
}); err != nil {
|
||||
return fmt.Errorf("notify watchers '%d/%d': %v", actUser.Id, repo.ID, err)
|
||||
}
|
||||
|
||||
@@ -52,6 +52,11 @@ func (n *Notice) TrStr() string {
|
||||
|
||||
// CreateNotice creates new system notice.
|
||||
func CreateNotice(tp NoticeType, desc string) error {
|
||||
// prevent panic if database connection is not available at this point
|
||||
if x == nil {
|
||||
return fmt.Errorf("Could not save notice due database connection not being available: %d %s", tp, desc)
|
||||
}
|
||||
|
||||
n := &Notice{
|
||||
Type: tp,
|
||||
Description: desc,
|
||||
@@ -69,7 +74,12 @@ func CreateRepositoryNotice(desc string) error {
|
||||
// creates a system notice when error occurs.
|
||||
func RemoveAllWithNotice(title, path string) {
|
||||
var err error
|
||||
// workaround for Go not being able to remove read-only files/folders: https://github.com/golang/go/issues/9606
|
||||
// this bug should be fixed on Go 1.7, so the workaround should be removed when Gogs don't support Go 1.6 anymore:
|
||||
// https://github.com/golang/go/commit/2ffb3e5d905b5622204d199128dec06cefd57790
|
||||
if setting.IsWindows {
|
||||
// converting "/" to "\" in path on Windows
|
||||
path = strings.Replace(path, "/", "\\", -1)
|
||||
err = exec.Command("cmd", "/C", "rmdir", "/S", "/Q", path).Run()
|
||||
} else {
|
||||
err = os.RemoveAll(path)
|
||||
|
||||
@@ -280,6 +280,18 @@ func (err ErrAccessTokenNotExist) Error() string {
|
||||
return fmt.Sprintf("access token does not exist [sha: %s]", err.SHA)
|
||||
}
|
||||
|
||||
type ErrAccessTokenEmpty struct {
|
||||
}
|
||||
|
||||
func IsErrAccessTokenEmpty(err error) bool {
|
||||
_, ok := err.(ErrAccessTokenEmpty)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrAccessTokenEmpty) Error() string {
|
||||
return fmt.Sprintf("access token is empty")
|
||||
}
|
||||
|
||||
// ________ .__ __ .__
|
||||
// \_____ \_______ _________ ____ |__|____________ _/ |_|__| ____ ____
|
||||
// / | \_ __ \/ ___\__ \ / \| \___ /\__ \\ __\ |/ _ \ / \
|
||||
|
||||
@@ -48,10 +48,10 @@ const (
|
||||
)
|
||||
|
||||
type DiffLine struct {
|
||||
LeftIdx int
|
||||
RightIdx int
|
||||
Type DiffLineType
|
||||
Content string
|
||||
LeftIdx int
|
||||
RightIdx int
|
||||
Type DiffLineType
|
||||
Content string
|
||||
}
|
||||
|
||||
func (d *DiffLine) GetType() int {
|
||||
@@ -161,6 +161,7 @@ type DiffFile struct {
|
||||
IsBin bool
|
||||
IsRenamed bool
|
||||
Sections []*DiffSection
|
||||
IsIncomplete bool
|
||||
}
|
||||
|
||||
func (diffFile *DiffFile) GetType() int {
|
||||
@@ -174,6 +175,7 @@ func (diffFile *DiffFile) GetHighlightClass() string {
|
||||
type Diff struct {
|
||||
TotalAddition, TotalDeletion int
|
||||
Files []*DiffFile
|
||||
IsIncomplete bool
|
||||
}
|
||||
|
||||
func (diff *Diff) NumFiles() int {
|
||||
@@ -182,7 +184,7 @@ func (diff *Diff) NumFiles() int {
|
||||
|
||||
const DIFF_HEAD = "diff --git "
|
||||
|
||||
func ParsePatch(maxlines int, reader io.Reader) (*Diff, error) {
|
||||
func ParsePatch(maxLines, maxLineCharacteres, maxFiles int, reader io.Reader) (*Diff, error) {
|
||||
var (
|
||||
diff = &Diff{Files: make([]*DiffFile, 0)}
|
||||
|
||||
@@ -193,15 +195,12 @@ func ParsePatch(maxlines int, reader io.Reader) (*Diff, error) {
|
||||
|
||||
leftLine, rightLine int
|
||||
lineCount int
|
||||
curFileLinesCount int
|
||||
)
|
||||
|
||||
input := bufio.NewReader(reader)
|
||||
isEOF := false
|
||||
for {
|
||||
if isEOF {
|
||||
break
|
||||
}
|
||||
|
||||
for !isEOF {
|
||||
line, err := input.ReadString('\n')
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
@@ -216,20 +215,16 @@ func ParsePatch(maxlines int, reader io.Reader) (*Diff, error) {
|
||||
line = line[:len(line)-1]
|
||||
}
|
||||
|
||||
if strings.HasPrefix(line, "+++ ") || strings.HasPrefix(line, "--- ") {
|
||||
continue
|
||||
} else if len(line) == 0 {
|
||||
if strings.HasPrefix(line, "+++ ") || strings.HasPrefix(line, "--- ") || len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
curFileLinesCount++
|
||||
lineCount++
|
||||
|
||||
// Diff data too large, we only show the first about maxlines lines
|
||||
if lineCount >= maxlines {
|
||||
log.Warn("Diff data too large")
|
||||
io.Copy(ioutil.Discard, reader)
|
||||
diff.Files = nil
|
||||
return diff, nil
|
||||
if curFileLinesCount >= maxLines || len(line) >= maxLineCharacteres {
|
||||
curFile.IsIncomplete = true
|
||||
}
|
||||
|
||||
switch {
|
||||
@@ -304,6 +299,12 @@ func ParsePatch(maxlines int, reader io.Reader) (*Diff, error) {
|
||||
Sections: make([]*DiffSection, 0, 10),
|
||||
}
|
||||
diff.Files = append(diff.Files, curFile)
|
||||
if len(diff.Files) >= maxFiles {
|
||||
diff.IsIncomplete = true
|
||||
io.Copy(ioutil.Discard, reader)
|
||||
break
|
||||
}
|
||||
curFileLinesCount = 0
|
||||
|
||||
// Check file diff type.
|
||||
for {
|
||||
@@ -366,7 +367,7 @@ func ParsePatch(maxlines int, reader io.Reader) (*Diff, error) {
|
||||
return diff, nil
|
||||
}
|
||||
|
||||
func GetDiffRange(repoPath, beforeCommitID string, afterCommitID string, maxlines int) (*Diff, error) {
|
||||
func GetDiffRange(repoPath, beforeCommitID string, afterCommitID string, maxLines, maxLineCharacteres, maxFiles int) (*Diff, error) {
|
||||
repo, err := git.OpenRepository(repoPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -405,7 +406,7 @@ func GetDiffRange(repoPath, beforeCommitID string, afterCommitID string, maxline
|
||||
pid := process.Add(fmt.Sprintf("GetDiffRange (%s)", repoPath), cmd)
|
||||
defer process.Remove(pid)
|
||||
|
||||
diff, err := ParsePatch(maxlines, stdout)
|
||||
diff, err := ParsePatch(maxLines, maxLineCharacteres, maxFiles, stdout)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ParsePatch: %v", err)
|
||||
}
|
||||
@@ -417,6 +418,6 @@ func GetDiffRange(repoPath, beforeCommitID string, afterCommitID string, maxline
|
||||
return diff, nil
|
||||
}
|
||||
|
||||
func GetDiffCommit(repoPath, commitId string, maxlines int) (*Diff, error) {
|
||||
return GetDiffRange(repoPath, "", commitId, maxlines)
|
||||
func GetDiffCommit(repoPath, commitId string, maxLines, maxLineCharacteres, maxFiles int) (*Diff, error) {
|
||||
return GetDiffRange(repoPath, "", commitId, maxLines, maxLineCharacteres, maxFiles)
|
||||
}
|
||||
|
||||
288
models/issue.go
288
models/issue.go
@@ -5,7 +5,6 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -33,8 +32,8 @@ var (
|
||||
// Issue represents an issue or pull request of repository.
|
||||
type Issue struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64 `xorm:"INDEX"`
|
||||
Index int64 // Index in one repository.
|
||||
RepoID int64 `xorm:"INDEX UNIQUE(repo_index)"`
|
||||
Index int64 `xorm:"UNIQUE(repo_index)"` // Index in one repository.
|
||||
Name string
|
||||
Repo *Repository `xorm:"-"`
|
||||
PosterID int64
|
||||
@@ -74,6 +73,19 @@ func (i *Issue) BeforeUpdate() {
|
||||
i.DeadlineUnix = i.Deadline.UTC().Unix()
|
||||
}
|
||||
|
||||
func (issue *Issue) loadAttributes(e Engine) (err error) {
|
||||
issue.Repo, err = getRepositoryByID(e, issue.RepoID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getRepositoryByID: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (issue *Issue) LoadAttributes() (err error) {
|
||||
return issue.loadAttributes(x)
|
||||
}
|
||||
|
||||
func (i *Issue) AfterSet(colName string, _ xorm.Cell) {
|
||||
var err error
|
||||
switch colName {
|
||||
@@ -147,6 +159,10 @@ func (i *Issue) State() string {
|
||||
return "open"
|
||||
}
|
||||
|
||||
func (issue *Issue) FullLink() string {
|
||||
return fmt.Sprintf("%s/issues/%d", issue.Repo.FullLink(), issue.Index)
|
||||
}
|
||||
|
||||
// IsPoster returns true if given user by ID is the poster.
|
||||
func (i *Issue) IsPoster(uid int64) bool {
|
||||
return i.PosterID == uid
|
||||
@@ -391,7 +407,7 @@ func newIssue(e *xorm.Session, repo *Repository, issue *Issue, labelIDs []int64,
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return issue.loadAttributes(e)
|
||||
}
|
||||
|
||||
// NewIssue creates new issue with labels for repository.
|
||||
@@ -423,7 +439,9 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
|
||||
IsPrivate: repo.IsPrivate,
|
||||
}
|
||||
if err = NotifyWatchers(act); err != nil {
|
||||
log.Error(4, "notifyWatchers: %v", err)
|
||||
log.Error(4, "NotifyWatchers: %v", err)
|
||||
} else if err = issue.MailParticipants(); err != nil {
|
||||
log.Error(4, "MailParticipants: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -452,8 +470,7 @@ func GetIssueByRef(ref string) (*Issue, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
issue.Repo = repo
|
||||
return issue, nil
|
||||
return issue, issue.LoadAttributes()
|
||||
}
|
||||
|
||||
// GetIssueByIndex returns issue by given index in repository.
|
||||
@@ -468,7 +485,7 @@ func GetIssueByIndex(repoID, index int64) (*Issue, error) {
|
||||
} else if !has {
|
||||
return nil, ErrIssueNotExist{0, repoID, index}
|
||||
}
|
||||
return issue, nil
|
||||
return issue, issue.LoadAttributes()
|
||||
}
|
||||
|
||||
// GetIssueByID returns an issue by given ID.
|
||||
@@ -480,7 +497,7 @@ func GetIssueByID(id int64) (*Issue, error) {
|
||||
} else if !has {
|
||||
return nil, ErrIssueNotExist{id, 0, 0}
|
||||
}
|
||||
return issue, nil
|
||||
return issue, issue.LoadAttributes()
|
||||
}
|
||||
|
||||
type IssuesOptions struct {
|
||||
@@ -513,7 +530,7 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) {
|
||||
if len(opts.RepoIDs) == 0 {
|
||||
return make([]*Issue, 0), nil
|
||||
}
|
||||
sess.Where("issue.repo_id IN ("+strings.Join(base.Int64sToStrings(opts.RepoIDs), ",")+")").And("issue.is_closed=?", opts.IsClosed)
|
||||
sess.In("issue.repo_id", base.Int64sToStrings(opts.RepoIDs)).And("issue.is_closed=?", opts.IsClosed)
|
||||
} else {
|
||||
sess.Where("issue.is_closed=?", opts.IsClosed)
|
||||
}
|
||||
@@ -532,43 +549,34 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) {
|
||||
|
||||
switch opts.SortType {
|
||||
case "oldest":
|
||||
sess.Asc("created_unix")
|
||||
sess.Asc("issue.created_unix")
|
||||
case "recentupdate":
|
||||
sess.Desc("updated_unix")
|
||||
sess.Desc("issue.updated_unix")
|
||||
case "leastupdate":
|
||||
sess.Asc("updated_unix")
|
||||
sess.Asc("issue.updated_unix")
|
||||
case "mostcomment":
|
||||
sess.Desc("num_comments")
|
||||
sess.Desc("issue.num_comments")
|
||||
case "leastcomment":
|
||||
sess.Asc("num_comments")
|
||||
sess.Asc("issue.num_comments")
|
||||
case "priority":
|
||||
sess.Desc("priority")
|
||||
sess.Desc("issue.priority")
|
||||
default:
|
||||
sess.Desc("created_unix")
|
||||
sess.Desc("issue.created_unix")
|
||||
}
|
||||
|
||||
labelIDs := base.StringsToInt64s(strings.Split(opts.Labels, ","))
|
||||
if len(labelIDs) > 0 {
|
||||
validJoin := false
|
||||
queryStr := "issue.id=issue_label.issue_id"
|
||||
for _, id := range labelIDs {
|
||||
if id == 0 {
|
||||
continue
|
||||
}
|
||||
validJoin = true
|
||||
queryStr += " AND issue_label.label_id=" + com.ToStr(id)
|
||||
}
|
||||
if validJoin {
|
||||
sess.Join("INNER", "issue_label", queryStr)
|
||||
if len(opts.Labels) > 0 && opts.Labels != "0" {
|
||||
labelIDs := base.StringsToInt64s(strings.Split(opts.Labels, ","))
|
||||
if len(labelIDs) > 0 {
|
||||
sess.Join("INNER", "issue_label", "issue.id = issue_label.issue_id").In("issue.label_id", labelIDs)
|
||||
}
|
||||
}
|
||||
|
||||
if opts.IsMention {
|
||||
queryStr := "issue.id=issue_user.issue_id AND issue_user.is_mentioned=1"
|
||||
sess.Join("INNER", "issue_user", "issue.id = issue_user.issue_id").And("issue_user.is_mentioned = ?", true)
|
||||
|
||||
if opts.UserID > 0 {
|
||||
queryStr += " AND issue_user.uid=" + com.ToStr(opts.UserID)
|
||||
sess.And("issue_user.uid = ?", opts.UserID)
|
||||
}
|
||||
sess.Join("INNER", "issue_user", queryStr)
|
||||
}
|
||||
|
||||
issues := make([]*Issue, 0, setting.IssuePagingNum)
|
||||
@@ -684,18 +692,8 @@ func GetIssueUserPairsByRepoIds(rids []int64, isClosed bool, page int) ([]*Issue
|
||||
return []*IssueUser{}, nil
|
||||
}
|
||||
|
||||
buf := bytes.NewBufferString("")
|
||||
for _, rid := range rids {
|
||||
buf.WriteString("repo_id=")
|
||||
buf.WriteString(com.ToStr(rid))
|
||||
buf.WriteString(" OR ")
|
||||
}
|
||||
cond := strings.TrimSuffix(buf.String(), " OR ")
|
||||
ius := make([]*IssueUser, 0, 10)
|
||||
sess := x.Limit(20, (page-1)*20).Where("is_closed=?", isClosed)
|
||||
if len(cond) > 0 {
|
||||
sess.And(cond)
|
||||
}
|
||||
sess := x.Limit(20, (page-1)*20).Where("is_closed=?", isClosed).In("repo_id", rids)
|
||||
err := sess.Find(&ius)
|
||||
return ius, err
|
||||
}
|
||||
@@ -720,42 +718,44 @@ func GetIssueUserPairsByMode(uid, rid int64, isClosed bool, page, filterMode int
|
||||
return ius, err
|
||||
}
|
||||
|
||||
func UpdateMentions(userNames []string, issueId int64) error {
|
||||
for i := range userNames {
|
||||
userNames[i] = strings.ToLower(userNames[i])
|
||||
}
|
||||
users := make([]*User, 0, len(userNames))
|
||||
|
||||
if err := x.Where("lower_name IN (?)", strings.Join(userNames, "\",\"")).OrderBy("lower_name ASC").Find(&users); err != nil {
|
||||
return err
|
||||
// UpdateIssueMentions extracts mentioned people from content and
|
||||
// updates issue-user relations for them.
|
||||
func UpdateIssueMentions(issueID int64, mentions []string) error {
|
||||
if len(mentions) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
ids := make([]int64, 0, len(userNames))
|
||||
for i := range mentions {
|
||||
mentions[i] = strings.ToLower(mentions[i])
|
||||
}
|
||||
users := make([]*User, 0, len(mentions))
|
||||
|
||||
if err := x.In("lower_name", mentions).Asc("lower_name").Find(&users); err != nil {
|
||||
return fmt.Errorf("find mentioned users: %v", err)
|
||||
}
|
||||
|
||||
ids := make([]int64, 0, len(mentions))
|
||||
for _, user := range users {
|
||||
ids = append(ids, user.Id)
|
||||
if !user.IsOrganization() {
|
||||
if !user.IsOrganization() || user.NumMembers == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if user.NumMembers == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
tempIds := make([]int64, 0, user.NumMembers)
|
||||
orgUsers, err := GetOrgUsersByOrgId(user.Id)
|
||||
memberIDs := make([]int64, 0, user.NumMembers)
|
||||
orgUsers, err := GetOrgUsersByOrgID(user.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("GetOrgUsersByOrgID [%d]: %v", user.Id, err)
|
||||
}
|
||||
|
||||
for _, orgUser := range orgUsers {
|
||||
tempIds = append(tempIds, orgUser.ID)
|
||||
memberIDs = append(memberIDs, orgUser.ID)
|
||||
}
|
||||
|
||||
ids = append(ids, tempIds...)
|
||||
ids = append(ids, memberIDs...)
|
||||
}
|
||||
|
||||
if err := UpdateIssueUsersByMentions(ids, issueId); err != nil {
|
||||
return err
|
||||
if err := UpdateIssueUsersByMentions(issueID, ids); err != nil {
|
||||
return fmt.Errorf("UpdateIssueUsersByMentions: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -791,7 +791,7 @@ func parseCountResult(results []map[string][]byte) int64 {
|
||||
type IssueStatsOptions struct {
|
||||
RepoID int64
|
||||
UserID int64
|
||||
LabelID int64
|
||||
Labels string
|
||||
MilestoneID int64
|
||||
AssigneeID int64
|
||||
FilterMode int
|
||||
@@ -802,41 +802,60 @@ type IssueStatsOptions struct {
|
||||
func GetIssueStats(opts *IssueStatsOptions) *IssueStats {
|
||||
stats := &IssueStats{}
|
||||
|
||||
queryStr := "SELECT COUNT(*) FROM `issue` "
|
||||
if opts.LabelID > 0 {
|
||||
queryStr += "INNER JOIN `issue_label` ON `issue`.id=`issue_label`.issue_id AND `issue_label`.label_id=" + com.ToStr(opts.LabelID)
|
||||
}
|
||||
countSession := func(opts *IssueStatsOptions) *xorm.Session {
|
||||
sess := x.Where("issue.repo_id = ?", opts.RepoID).And("is_pull = ?", opts.IsPull)
|
||||
|
||||
baseCond := " WHERE issue.repo_id=" + com.ToStr(opts.RepoID) + " AND issue.is_closed=?"
|
||||
if opts.MilestoneID > 0 {
|
||||
baseCond += " AND issue.milestone_id=" + com.ToStr(opts.MilestoneID)
|
||||
if len(opts.Labels) > 0 && opts.Labels != "0" {
|
||||
labelIDs := base.StringsToInt64s(strings.Split(opts.Labels, ","))
|
||||
if len(labelIDs) > 0 {
|
||||
sess.Join("INNER", "issue_label", "issue.id = issue_id").In("label_id", labelIDs)
|
||||
}
|
||||
}
|
||||
|
||||
if opts.MilestoneID > 0 {
|
||||
sess.And("issue.milestone_id = ?", opts.MilestoneID)
|
||||
}
|
||||
|
||||
if opts.AssigneeID > 0 {
|
||||
sess.And("assignee_id = ?", opts.AssigneeID)
|
||||
}
|
||||
|
||||
return sess
|
||||
}
|
||||
if opts.AssigneeID > 0 {
|
||||
baseCond += " AND assignee_id=" + com.ToStr(opts.AssigneeID)
|
||||
}
|
||||
baseCond += " AND issue.is_pull=?"
|
||||
|
||||
switch opts.FilterMode {
|
||||
case FM_ALL, FM_ASSIGN:
|
||||
results, _ := x.Query(queryStr+baseCond, false, opts.IsPull)
|
||||
stats.OpenCount = parseCountResult(results)
|
||||
results, _ = x.Query(queryStr+baseCond, true, opts.IsPull)
|
||||
stats.ClosedCount = parseCountResult(results)
|
||||
stats.OpenCount, _ = countSession(opts).
|
||||
And("is_closed = ?", false).
|
||||
Count(&Issue{})
|
||||
|
||||
stats.ClosedCount, _ = countSession(opts).
|
||||
And("is_closed = ?", true).
|
||||
Count(&Issue{})
|
||||
case FM_CREATE:
|
||||
baseCond += " AND poster_id=?"
|
||||
results, _ := x.Query(queryStr+baseCond, false, opts.IsPull, opts.UserID)
|
||||
stats.OpenCount = parseCountResult(results)
|
||||
results, _ = x.Query(queryStr+baseCond, true, opts.IsPull, opts.UserID)
|
||||
stats.ClosedCount = parseCountResult(results)
|
||||
stats.OpenCount, _ = countSession(opts).
|
||||
And("poster_id = ?", opts.UserID).
|
||||
And("is_closed = ?", false).
|
||||
Count(&Issue{})
|
||||
|
||||
stats.ClosedCount, _ = countSession(opts).
|
||||
And("poster_id = ?", opts.UserID).
|
||||
And("is_closed = ?", true).
|
||||
Count(&Issue{})
|
||||
case FM_MENTION:
|
||||
queryStr += " INNER JOIN `issue_user` ON `issue`.id=`issue_user`.issue_id"
|
||||
baseCond += " AND `issue_user`.uid=? AND `issue_user`.is_mentioned=?"
|
||||
results, _ := x.Query(queryStr+baseCond, false, opts.IsPull, opts.UserID, true)
|
||||
stats.OpenCount = parseCountResult(results)
|
||||
results, _ = x.Query(queryStr+baseCond, true, opts.IsPull, opts.UserID, true)
|
||||
stats.ClosedCount = parseCountResult(results)
|
||||
stats.OpenCount, _ = countSession(opts).
|
||||
Join("INNER", "issue_user", "issue.id = issue_user.issue_id").
|
||||
And("issue_user.uid = ?", opts.UserID).
|
||||
And("issue_user.is_mentioned = ?", true).
|
||||
And("issue.is_closed = ?", false).
|
||||
Count(&Issue{})
|
||||
|
||||
stats.ClosedCount, _ = countSession(opts).
|
||||
Join("INNER", "issue_user", "issue.id = issue_user.issue_id").
|
||||
And("issue_user.uid = ?", opts.UserID).
|
||||
And("issue_user.is_mentioned = ?", true).
|
||||
And("issue.is_closed = ?", true).
|
||||
Count(&Issue{})
|
||||
}
|
||||
return stats
|
||||
}
|
||||
@@ -845,64 +864,70 @@ func GetIssueStats(opts *IssueStatsOptions) *IssueStats {
|
||||
func GetUserIssueStats(repoID, uid int64, repoIDs []int64, filterMode int, isPull bool) *IssueStats {
|
||||
stats := &IssueStats{}
|
||||
|
||||
queryStr := "SELECT COUNT(*) FROM `issue` "
|
||||
baseCond := " WHERE issue.is_closed=?"
|
||||
if repoID > 0 || len(repoIDs) == 0 {
|
||||
baseCond += " AND issue.repo_id=" + com.ToStr(repoID)
|
||||
} else {
|
||||
baseCond += " AND issue.repo_id IN (" + strings.Join(base.Int64sToStrings(repoIDs), ",") + ")"
|
||||
countSession := func(isClosed, isPull bool, repoID int64, repoIDs []int64) *xorm.Session {
|
||||
sess := x.Where("issue.is_closed = ?", isClosed).And("issue.is_pull = ?", isPull)
|
||||
|
||||
if repoID > 0 || len(repoIDs) == 0 {
|
||||
sess.And("repo_id = ?", repoID)
|
||||
} else {
|
||||
sess.In("repo_id", repoIDs)
|
||||
}
|
||||
|
||||
return sess
|
||||
}
|
||||
|
||||
if isPull {
|
||||
baseCond += " AND issue.is_pull=1"
|
||||
} else {
|
||||
baseCond += " AND issue.is_pull=0"
|
||||
}
|
||||
stats.AssignCount, _ = countSession(false, isPull, repoID, repoIDs).
|
||||
And("assignee_id = ?", uid).
|
||||
Count(&Issue{})
|
||||
|
||||
results, _ := x.Query(queryStr+baseCond+" AND assignee_id=?", false, uid)
|
||||
stats.AssignCount = parseCountResult(results)
|
||||
results, _ = x.Query(queryStr+baseCond+" AND poster_id=?", false, uid)
|
||||
stats.CreateCount = parseCountResult(results)
|
||||
stats.CreateCount, _ = countSession(false, isPull, repoID, repoIDs).
|
||||
And("assignee_id = ?", uid).
|
||||
Count(&Issue{})
|
||||
|
||||
openCountSession := countSession(false, isPull, repoID, repoIDs)
|
||||
closedCountSession := countSession(true, isPull, repoID, repoIDs)
|
||||
|
||||
switch filterMode {
|
||||
case FM_ASSIGN:
|
||||
baseCond += " AND assignee_id=" + com.ToStr(uid)
|
||||
|
||||
openCountSession.And("assignee_id = ?", uid)
|
||||
closedCountSession.And("assignee_id = ?", uid)
|
||||
case FM_CREATE:
|
||||
baseCond += " AND poster_id=" + com.ToStr(uid)
|
||||
openCountSession.And("poster_id = ?", uid)
|
||||
closedCountSession.And("poster_id = ?", uid)
|
||||
}
|
||||
|
||||
results, _ = x.Query(queryStr+baseCond, false)
|
||||
stats.OpenCount = parseCountResult(results)
|
||||
results, _ = x.Query(queryStr+baseCond, true)
|
||||
stats.ClosedCount = parseCountResult(results)
|
||||
stats.OpenCount, _ = openCountSession.Count(&Issue{})
|
||||
stats.ClosedCount, _ = closedCountSession.Count(&Issue{})
|
||||
|
||||
return stats
|
||||
}
|
||||
|
||||
// GetRepoIssueStats returns number of open and closed repository issues by given filter mode.
|
||||
func GetRepoIssueStats(repoID, uid int64, filterMode int, isPull bool) (numOpen int64, numClosed int64) {
|
||||
queryStr := "SELECT COUNT(*) FROM `issue` "
|
||||
baseCond := " WHERE issue.repo_id=? AND issue.is_closed=?"
|
||||
countSession := func(isClosed, isPull bool, repoID int64) *xorm.Session {
|
||||
sess := x.Where("issue.repo_id = ?", isClosed).
|
||||
And("is_pull = ?", isPull).
|
||||
And("repo_id = ?", repoID)
|
||||
|
||||
if isPull {
|
||||
baseCond += " AND issue.is_pull=1"
|
||||
} else {
|
||||
baseCond += " AND issue.is_pull=0"
|
||||
return sess
|
||||
}
|
||||
|
||||
openCountSession := countSession(false, isPull, repoID)
|
||||
closedCountSession := countSession(true, isPull, repoID)
|
||||
|
||||
switch filterMode {
|
||||
case FM_ASSIGN:
|
||||
baseCond += " AND assignee_id=" + com.ToStr(uid)
|
||||
|
||||
openCountSession.And("assignee_id = ?", uid)
|
||||
closedCountSession.And("assignee_id = ?", uid)
|
||||
case FM_CREATE:
|
||||
baseCond += " AND poster_id=" + com.ToStr(uid)
|
||||
openCountSession.And("poster_id = ?", uid)
|
||||
closedCountSession.And("poster_id = ?", uid)
|
||||
}
|
||||
|
||||
results, _ := x.Query(queryStr+baseCond, repoID, false)
|
||||
numOpen = parseCountResult(results)
|
||||
results, _ = x.Query(queryStr+baseCond, repoID, true)
|
||||
numClosed = parseCountResult(results)
|
||||
return numOpen, numClosed
|
||||
openResult, _ := openCountSession.Count(&Issue{})
|
||||
closedResult, _ := closedCountSession.Count(&Issue{})
|
||||
|
||||
return openResult, closedResult
|
||||
}
|
||||
|
||||
func updateIssue(e Engine, issue *Issue) error {
|
||||
@@ -968,9 +993,12 @@ func UpdateIssueUserByRead(uid, issueID int64) error {
|
||||
}
|
||||
|
||||
// UpdateIssueUsersByMentions updates issue-user pairs by mentioning.
|
||||
func UpdateIssueUsersByMentions(uids []int64, iid int64) error {
|
||||
func UpdateIssueUsersByMentions(issueID int64, uids []int64) error {
|
||||
for _, uid := range uids {
|
||||
iu := &IssueUser{UID: uid, IssueID: iid}
|
||||
iu := &IssueUser{
|
||||
UID: uid,
|
||||
IssueID: issueID,
|
||||
}
|
||||
has, err := x.Get(iu)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/go-xorm/xorm"
|
||||
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/markdown"
|
||||
)
|
||||
|
||||
// CommentType defines whether a comment is just a simple comment, an action (like close) or a reference.
|
||||
@@ -113,10 +114,34 @@ func (c *Comment) EventTag() string {
|
||||
return "event-" + com.ToStr(c.ID)
|
||||
}
|
||||
|
||||
// MailParticipants sends new comment emails to repository watchers
|
||||
// and mentioned people.
|
||||
func (cmt *Comment) MailParticipants(opType ActionType, issue *Issue) (err error) {
|
||||
mentions := markdown.FindAllMentions(cmt.Content)
|
||||
if err = UpdateIssueMentions(cmt.IssueID, mentions); err != nil {
|
||||
return fmt.Errorf("UpdateIssueMentions [%d]: %v", cmt.IssueID, err)
|
||||
}
|
||||
|
||||
switch opType {
|
||||
case ACTION_COMMENT_ISSUE:
|
||||
issue.Content = cmt.Content
|
||||
case ACTION_CLOSE_ISSUE:
|
||||
issue.Content = fmt.Sprintf("Closed #%d", issue.Index)
|
||||
case ACTION_REOPEN_ISSUE:
|
||||
issue.Content = fmt.Sprintf("Reopened #%d", issue.Index)
|
||||
}
|
||||
if err = mailIssueCommentToParticipants(issue, cmt.Poster, mentions); err != nil {
|
||||
log.Error(4, "mailIssueCommentToParticipants: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err error) {
|
||||
comment := &Comment{
|
||||
Type: opts.Type,
|
||||
PosterID: opts.Doer.Id,
|
||||
Poster: opts.Doer,
|
||||
IssueID: opts.Issue.ID,
|
||||
CommitID: opts.CommitID,
|
||||
CommitSHA: opts.CommitSHA,
|
||||
@@ -157,7 +182,7 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
|
||||
if IsErrAttachmentNotExist(err) {
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("getAttachmentByUUID[%s]: %v", uuid, err)
|
||||
return nil, fmt.Errorf("getAttachmentByUUID [%s]: %v", uuid, err)
|
||||
}
|
||||
attachments = append(attachments, attach)
|
||||
}
|
||||
@@ -167,7 +192,7 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
|
||||
attachments[i].CommentID = comment.ID
|
||||
// No assign value could be 0, so ignore AllCols().
|
||||
if _, err = e.Id(attachments[i].ID).Update(attachments[i]); err != nil {
|
||||
return nil, fmt.Errorf("update attachment[%d]: %v", attachments[i].ID, err)
|
||||
return nil, fmt.Errorf("update attachment [%d]: %v", attachments[i].ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,13 +225,15 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Notify watchers for whatever action comes in, ignore if no action type
|
||||
// Notify watchers for whatever action comes in, ignore if no action type.
|
||||
if act.OpType > 0 {
|
||||
if err = notifyWatchers(e, act); err != nil {
|
||||
return nil, fmt.Errorf("notifyWatchers: %v", err)
|
||||
log.Error(4, "notifyWatchers: %v", err)
|
||||
}
|
||||
comment.MailParticipants(act.OpType, opts.Issue)
|
||||
}
|
||||
|
||||
return comment, nil
|
||||
|
||||
81
models/issue_mail.go
Normal file
81
models/issue_mail.go
Normal file
@@ -0,0 +1,81 @@
|
||||
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/markdown"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
func (issue *Issue) MailSubject() string {
|
||||
return fmt.Sprintf("[%s] %s (#%d)", issue.Repo.Name, issue.Name, issue.Index)
|
||||
}
|
||||
|
||||
// mailIssueCommentToParticipants can be used for both new issue creation and comment.
|
||||
func mailIssueCommentToParticipants(issue *Issue, doer *User, mentions []string) error {
|
||||
if !setting.Service.EnableNotifyMail {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Mail wahtcers.
|
||||
watchers, err := GetWatchers(issue.RepoID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetWatchers [%d]: %v", issue.RepoID, err)
|
||||
}
|
||||
|
||||
tos := make([]string, 0, len(watchers)) // List of email addresses.
|
||||
names := make([]string, 0, len(watchers))
|
||||
for i := range watchers {
|
||||
if watchers[i].UserID == doer.Id {
|
||||
continue
|
||||
}
|
||||
|
||||
to, err := GetUserByID(watchers[i].UserID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetUserByID [%d]: %v", watchers[i].UserID, err)
|
||||
}
|
||||
if to.IsOrganization() {
|
||||
continue
|
||||
}
|
||||
|
||||
tos = append(tos, to.Email)
|
||||
names = append(names, to.Name)
|
||||
}
|
||||
SendIssueCommentMail(issue, doer, tos)
|
||||
|
||||
// Mail mentioned people and exclude watchers.
|
||||
names = append(names, doer.Name)
|
||||
tos = make([]string, 0, len(mentions)) // list of user names.
|
||||
for i := range mentions {
|
||||
if com.IsSliceContainsStr(names, mentions[i]) {
|
||||
continue
|
||||
}
|
||||
|
||||
tos = append(tos, mentions[i])
|
||||
}
|
||||
SendIssueMentionMail(issue, doer, GetUserEmailsByNames(tos))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MailParticipants sends new issue thread created emails to repository watchers
|
||||
// and mentioned people.
|
||||
func (issue *Issue) MailParticipants() (err error) {
|
||||
mentions := markdown.FindAllMentions(issue.Content)
|
||||
if err = UpdateIssueMentions(issue.ID, mentions); err != nil {
|
||||
return fmt.Errorf("UpdateIssueMentions [%d]: %v", issue.ID, err)
|
||||
}
|
||||
|
||||
if err = mailIssueCommentToParticipants(issue, issue.Poster, mentions); err != nil {
|
||||
log.Error(4, "mailIssueCommentToParticipants: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/go-macaron/binding"
|
||||
"github.com/go-xorm/core"
|
||||
"github.com/go-xorm/xorm"
|
||||
|
||||
@@ -23,6 +24,11 @@ import (
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrAuthenticationAlreadyExist = errors.New("Authentication already exist")
|
||||
ErrAuthenticationUserUsed = errors.New("Authentication has been used by some users")
|
||||
)
|
||||
|
||||
type LoginType int
|
||||
|
||||
// Note: new type must be added at the end of list to maintain compatibility.
|
||||
@@ -35,11 +41,6 @@ const (
|
||||
LOGIN_DLDAP // 5
|
||||
)
|
||||
|
||||
var (
|
||||
ErrAuthenticationAlreadyExist = errors.New("Authentication already exist")
|
||||
ErrAuthenticationUserUsed = errors.New("Authentication has been used by some users")
|
||||
)
|
||||
|
||||
var LoginNames = map[LoginType]string{
|
||||
LOGIN_LDAP: "LDAP (via BindDN)",
|
||||
LOGIN_DLDAP: "LDAP (simple auth)", // Via direct bind
|
||||
@@ -47,6 +48,12 @@ var LoginNames = map[LoginType]string{
|
||||
LOGIN_PAM: "PAM",
|
||||
}
|
||||
|
||||
var SecurityProtocolNames = map[ldap.SecurityProtocol]string{
|
||||
ldap.SECURITY_PROTOCOL_UNENCRYPTED: "Unencrypted",
|
||||
ldap.SECURITY_PROTOCOL_LDAPS: "LDAPS",
|
||||
ldap.SECURITY_PROTOCOL_START_TLS: "StartTLS",
|
||||
}
|
||||
|
||||
// Ensure structs implemented interface.
|
||||
var (
|
||||
_ core.Conversion = &LDAPConfig{}
|
||||
@@ -66,6 +73,10 @@ func (cfg *LDAPConfig) ToDB() ([]byte, error) {
|
||||
return json.Marshal(cfg)
|
||||
}
|
||||
|
||||
func (cfg *LDAPConfig) SecurityProtocolName() string {
|
||||
return SecurityProtocolNames[cfg.SecurityProtocol]
|
||||
}
|
||||
|
||||
type SMTPConfig struct {
|
||||
Auth string
|
||||
Host string
|
||||
@@ -173,10 +184,16 @@ func (source *LoginSource) IsPAM() bool {
|
||||
return source.Type == LOGIN_PAM
|
||||
}
|
||||
|
||||
func (source *LoginSource) HasTLS() bool {
|
||||
return ((source.IsLDAP() || source.IsDLDAP()) &&
|
||||
source.LDAP().SecurityProtocol > ldap.SECURITY_PROTOCOL_UNENCRYPTED) ||
|
||||
source.IsSMTP()
|
||||
}
|
||||
|
||||
func (source *LoginSource) UseTLS() bool {
|
||||
switch source.Type {
|
||||
case LOGIN_LDAP, LOGIN_DLDAP:
|
||||
return source.LDAP().UseSSL
|
||||
return source.LDAP().SecurityProtocol != ldap.SECURITY_PROTOCOL_UNENCRYPTED
|
||||
case LOGIN_SMTP:
|
||||
return source.SMTP().TLS
|
||||
}
|
||||
@@ -264,7 +281,7 @@ func DeleteSource(source *LoginSource) error {
|
||||
func LoginUserLDAPSource(u *User, loginName, passwd string, source *LoginSource, autoRegister bool) (*User, error) {
|
||||
cfg := source.Cfg.(*LDAPConfig)
|
||||
directBind := (source.Type == LOGIN_DLDAP)
|
||||
name, fn, sn, mail, admin, logged := cfg.SearchEntry(loginName, passwd, directBind)
|
||||
username, fn, sn, mail, isAdmin, logged := cfg.SearchEntry(loginName, passwd, directBind)
|
||||
if !logged {
|
||||
// User not in LDAP, do nothing
|
||||
return nil, ErrUserNotExist{0, loginName}
|
||||
@@ -275,37 +292,42 @@ func LoginUserLDAPSource(u *User, loginName, passwd string, source *LoginSource,
|
||||
}
|
||||
|
||||
// Fallback.
|
||||
if len(name) == 0 {
|
||||
name = loginName
|
||||
if len(username) == 0 {
|
||||
username = loginName
|
||||
}
|
||||
// Validate username make sure it satisfies requirement.
|
||||
if binding.AlphaDashDotPattern.MatchString(username) {
|
||||
return nil, fmt.Errorf("Invalid pattern for attribute 'username' [%s]: must be valid alpha or numeric or dash(-_) or dot characters", username)
|
||||
}
|
||||
|
||||
if len(mail) == 0 {
|
||||
mail = fmt.Sprintf("%s@localhost", name)
|
||||
mail = fmt.Sprintf("%s@localhost", username)
|
||||
}
|
||||
|
||||
u = &User{
|
||||
LowerName: strings.ToLower(name),
|
||||
Name: name,
|
||||
FullName: composeFullName(fn, sn, name),
|
||||
LowerName: strings.ToLower(username),
|
||||
Name: username,
|
||||
FullName: composeFullName(fn, sn, username),
|
||||
LoginType: source.Type,
|
||||
LoginSource: source.ID,
|
||||
LoginName: loginName,
|
||||
Email: mail,
|
||||
IsAdmin: admin,
|
||||
IsAdmin: isAdmin,
|
||||
IsActive: true,
|
||||
}
|
||||
return u, CreateUser(u)
|
||||
}
|
||||
|
||||
func composeFullName(firstName, surename, userName string) string {
|
||||
func composeFullName(firstname, surname, username string) string {
|
||||
switch {
|
||||
case len(firstName) == 0 && len(surename) == 0:
|
||||
return userName
|
||||
case len(firstName) == 0:
|
||||
return surename
|
||||
case len(surename) == 0:
|
||||
return firstName
|
||||
case len(firstname) == 0 && len(surname) == 0:
|
||||
return username
|
||||
case len(firstname) == 0:
|
||||
return surname
|
||||
case len(surname) == 0:
|
||||
return firstname
|
||||
default:
|
||||
return firstName + " " + surename
|
||||
return firstname + " " + surname
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
183
models/mail.go
Normal file
183
models/mail.go
Normal file
@@ -0,0 +1,183 @@
|
||||
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"path"
|
||||
|
||||
"gopkg.in/gomail.v2"
|
||||
"gopkg.in/macaron.v1"
|
||||
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/mailer"
|
||||
"github.com/gogits/gogs/modules/markdown"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
MAIL_AUTH_ACTIVATE base.TplName = "auth/activate"
|
||||
MAIL_AUTH_ACTIVATE_EMAIL base.TplName = "auth/activate_email"
|
||||
MAIL_AUTH_RESET_PASSWORD base.TplName = "auth/reset_passwd"
|
||||
MAIL_AUTH_REGISTER_NOTIFY base.TplName = "auth/register_notify"
|
||||
|
||||
MAIL_ISSUE_COMMENT base.TplName = "issue/comment"
|
||||
MAIL_ISSUE_MENTION base.TplName = "issue/mention"
|
||||
|
||||
MAIL_NOTIFY_COLLABORATOR base.TplName = "notify/collaborator"
|
||||
)
|
||||
|
||||
type MailRender interface {
|
||||
HTMLString(string, interface{}, ...macaron.HTMLOptions) (string, error)
|
||||
}
|
||||
|
||||
var mailRender MailRender
|
||||
|
||||
func InitMailRender(dir, appendDir string, funcMap []template.FuncMap) {
|
||||
opt := &macaron.RenderOptions{
|
||||
Directory: dir,
|
||||
AppendDirectories: []string{appendDir},
|
||||
Funcs: funcMap,
|
||||
Extensions: []string{".tmpl", ".html"},
|
||||
}
|
||||
ts := macaron.NewTemplateSet()
|
||||
ts.Set(macaron.DEFAULT_TPL_SET_NAME, opt)
|
||||
|
||||
mailRender = &macaron.TplRender{
|
||||
TemplateSet: ts,
|
||||
Opt: opt,
|
||||
}
|
||||
}
|
||||
|
||||
func SendTestMail(email string) error {
|
||||
return gomail.Send(&mailer.Sender{}, mailer.NewMessage([]string{email}, "Gogs Test Email!", "Gogs Test Email!").Message)
|
||||
}
|
||||
|
||||
func SendUserMail(c *macaron.Context, u *User, tpl base.TplName, code, subject, info string) {
|
||||
data := map[string]interface{}{
|
||||
"Username": u.DisplayName(),
|
||||
"ActiveCodeLives": setting.Service.ActiveCodeLives / 60,
|
||||
"ResetPwdCodeLives": setting.Service.ResetPwdCodeLives / 60,
|
||||
"Code": code,
|
||||
}
|
||||
body, err := mailRender.HTMLString(string(tpl), data)
|
||||
if err != nil {
|
||||
log.Error(3, "HTMLString: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
msg := mailer.NewMessage([]string{u.Email}, subject, body)
|
||||
msg.Info = fmt.Sprintf("UID: %d, %s", u.Id, info)
|
||||
|
||||
mailer.SendAsync(msg)
|
||||
}
|
||||
|
||||
func SendActivateAccountMail(c *macaron.Context, u *User) {
|
||||
SendUserMail(c, u, MAIL_AUTH_ACTIVATE, u.GenerateActivateCode(), c.Tr("mail.activate_account"), "activate account")
|
||||
}
|
||||
|
||||
func SendResetPasswordMail(c *macaron.Context, u *User) {
|
||||
SendUserMail(c, u, MAIL_AUTH_RESET_PASSWORD, u.GenerateActivateCode(), c.Tr("mail.reset_password"), "reset password")
|
||||
}
|
||||
|
||||
// SendActivateAccountMail sends confirmation email.
|
||||
func SendActivateEmailMail(c *macaron.Context, u *User, email *EmailAddress) {
|
||||
data := map[string]interface{}{
|
||||
"Username": u.DisplayName(),
|
||||
"ActiveCodeLives": setting.Service.ActiveCodeLives / 60,
|
||||
"Code": u.GenerateEmailActivateCode(email.Email),
|
||||
"Email": email.Email,
|
||||
}
|
||||
body, err := mailRender.HTMLString(string(MAIL_AUTH_ACTIVATE_EMAIL), data)
|
||||
if err != nil {
|
||||
log.Error(3, "HTMLString: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
msg := mailer.NewMessage([]string{email.Email}, c.Tr("mail.activate_email"), body)
|
||||
msg.Info = fmt.Sprintf("UID: %d, activate email", u.Id)
|
||||
|
||||
mailer.SendAsync(msg)
|
||||
}
|
||||
|
||||
// SendRegisterNotifyMail triggers a notify e-mail by admin created a account.
|
||||
func SendRegisterNotifyMail(c *macaron.Context, u *User) {
|
||||
data := map[string]interface{}{
|
||||
"Username": u.DisplayName(),
|
||||
}
|
||||
body, err := mailRender.HTMLString(string(MAIL_AUTH_REGISTER_NOTIFY), data)
|
||||
if err != nil {
|
||||
log.Error(3, "HTMLString: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
msg := mailer.NewMessage([]string{u.Email}, c.Tr("mail.register_notify"), body)
|
||||
msg.Info = fmt.Sprintf("UID: %d, registration notify", u.Id)
|
||||
|
||||
mailer.SendAsync(msg)
|
||||
}
|
||||
|
||||
// SendCollaboratorMail sends mail notification to new collaborator.
|
||||
func SendCollaboratorMail(u, doer *User, repo *Repository) {
|
||||
repoName := path.Join(repo.Owner.Name, repo.Name)
|
||||
subject := fmt.Sprintf("%s added you to %s", doer.DisplayName(), repoName)
|
||||
|
||||
data := map[string]interface{}{
|
||||
"Subject": subject,
|
||||
"RepoName": repoName,
|
||||
"Link": repo.FullLink(),
|
||||
}
|
||||
body, err := mailRender.HTMLString(string(MAIL_NOTIFY_COLLABORATOR), data)
|
||||
if err != nil {
|
||||
log.Error(3, "HTMLString: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
msg := mailer.NewMessage([]string{u.Email}, subject, body)
|
||||
msg.Info = fmt.Sprintf("UID: %d, add collaborator", u.Id)
|
||||
|
||||
mailer.SendAsync(msg)
|
||||
}
|
||||
|
||||
func composeTplData(subject, body, link string) map[string]interface{} {
|
||||
data := make(map[string]interface{}, 10)
|
||||
data["Subject"] = subject
|
||||
data["Body"] = body
|
||||
data["Link"] = link
|
||||
return data
|
||||
}
|
||||
|
||||
func composeIssueMessage(issue *Issue, doer *User, tplName base.TplName, tos []string, info string) *mailer.Message {
|
||||
subject := issue.MailSubject()
|
||||
body := string(markdown.RenderSpecialLink([]byte(issue.Content), issue.Repo.FullLink(), issue.Repo.ComposeMetas()))
|
||||
data := composeTplData(subject, body, issue.FullLink())
|
||||
data["Doer"] = doer
|
||||
content, err := mailRender.HTMLString(string(tplName), data)
|
||||
if err != nil {
|
||||
log.Error(3, "HTMLString (%s): %v", tplName, err)
|
||||
}
|
||||
msg := mailer.NewMessage(tos, subject, content)
|
||||
msg.Info = fmt.Sprintf("Subject: %s, %s", subject, info)
|
||||
return msg
|
||||
}
|
||||
|
||||
// SendIssueCommentMail composes and sends issue comment emails to target receivers.
|
||||
func SendIssueCommentMail(issue *Issue, doer *User, tos []string) {
|
||||
if len(tos) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
mailer.SendAsync(composeIssueMessage(issue, doer, MAIL_ISSUE_COMMENT, tos, "issue comment"))
|
||||
}
|
||||
|
||||
// SendIssueMentionMail composes and sends issue mention emails to target receivers.
|
||||
func SendIssueMentionMail(issue *Issue, doer *User, tos []string) {
|
||||
if len(tos) == 0 {
|
||||
return
|
||||
}
|
||||
mailer.SendAsync(composeIssueMessage(issue, doer, MAIL_ISSUE_MENTION, tos, "issue mention"))
|
||||
}
|
||||
@@ -51,7 +51,7 @@ func (m *migration) Migrate(x *xorm.Engine) error {
|
||||
|
||||
// The version table. Should have only one row with id==1
|
||||
type Version struct {
|
||||
Id int64
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Version int64
|
||||
}
|
||||
|
||||
@@ -59,14 +59,15 @@ type Version struct {
|
||||
// If you want to "retire" a migration, remove it from the top of the list and
|
||||
// update _MIN_VER_DB accordingly
|
||||
var migrations = []Migration{
|
||||
NewMigration("fix locale file load panic", fixLocaleFileLoadPanic), // V4 -> V5:v0.6.0
|
||||
NewMigration("trim action compare URL prefix", trimCommitActionAppUrlPrefix), // V5 -> V6:v0.6.3
|
||||
NewMigration("generate issue-label from issue", issueToIssueLabel), // V6 -> V7:v0.6.4
|
||||
NewMigration("refactor attachment table", attachmentRefactor), // V7 -> V8:v0.6.4
|
||||
NewMigration("rename pull request fields", renamePullRequestFields), // V8 -> V9:v0.6.16
|
||||
NewMigration("clean up migrate repo info", cleanUpMigrateRepoInfo), // V9 -> V10:v0.6.20
|
||||
NewMigration("generate rands and salt for organizations", generateOrgRandsAndSalt), // V10 -> V11:v0.8.5
|
||||
NewMigration("convert date to unix timestamp", convertDateToUnix), // V11 -> V12:v0.9.2
|
||||
NewMigration("fix locale file load panic", fixLocaleFileLoadPanic), // V4 -> V5:v0.6.0
|
||||
NewMigration("trim action compare URL prefix", trimCommitActionAppUrlPrefix), // V5 -> V6:v0.6.3
|
||||
NewMigration("generate issue-label from issue", issueToIssueLabel), // V6 -> V7:v0.6.4
|
||||
NewMigration("refactor attachment table", attachmentRefactor), // V7 -> V8:v0.6.4
|
||||
NewMigration("rename pull request fields", renamePullRequestFields), // V8 -> V9:v0.6.16
|
||||
NewMigration("clean up migrate repo info", cleanUpMigrateRepoInfo), // V9 -> V10:v0.6.20
|
||||
NewMigration("generate rands and salt for organizations", generateOrgRandsAndSalt), // V10 -> V11:v0.8.5
|
||||
NewMigration("convert date to unix timestamp", convertDateToUnix), // V11 -> V12:v0.9.2
|
||||
NewMigration("convert LDAP UseSSL option to SecurityProtocol", ldapUseSSLToSecurityProtocol), // V12 -> V13:v0.9.37
|
||||
}
|
||||
|
||||
// Migrate database to current version
|
||||
@@ -75,7 +76,7 @@ func Migrate(x *xorm.Engine) error {
|
||||
return fmt.Errorf("sync: %v", err)
|
||||
}
|
||||
|
||||
currentVersion := &Version{Id: 1}
|
||||
currentVersion := &Version{ID: 1}
|
||||
has, err := x.Get(currentVersion)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get: %v", err)
|
||||
@@ -580,6 +581,7 @@ type TWebhook struct {
|
||||
func (t *TWebhook) TableName() string { return "webhook" }
|
||||
|
||||
func convertDateToUnix(x *xorm.Engine) (err error) {
|
||||
log.Info("This migration could take up to minutes, please be patient.")
|
||||
type Bean struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Created time.Time
|
||||
|
||||
52
models/migrations/v13.go
Normal file
52
models/migrations/v13.go
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/go-xorm/xorm"
|
||||
)
|
||||
|
||||
func ldapUseSSLToSecurityProtocol(x *xorm.Engine) error {
|
||||
results, err := x.Query("SELECT `id`,`cfg` FROM `login_source` WHERE `type` = 2 OR `type` = 5")
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "no such column") {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("select LDAP login sources: %v", err)
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, result := range results {
|
||||
cfg := map[string]interface{}{}
|
||||
if err = json.Unmarshal(result["cfg"], &cfg); err != nil {
|
||||
return fmt.Errorf("decode JSON config: %v", err)
|
||||
}
|
||||
if com.ToStr(cfg["UseSSL"]) == "true" {
|
||||
cfg["SecurityProtocol"] = 1 // LDAPS
|
||||
}
|
||||
delete(cfg, "UseSSL")
|
||||
|
||||
data, err := json.Marshal(&cfg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("encode JSON config: %v", err)
|
||||
}
|
||||
|
||||
if _, err = sess.Exec("UPDATE `login_source` SET `cfg`=? WHERE `id`=?",
|
||||
string(data), com.StrTo(result["id"]).MustInt64()); err != nil {
|
||||
return fmt.Errorf("update config column: %v", err)
|
||||
}
|
||||
}
|
||||
return sess.Commit()
|
||||
}
|
||||
@@ -97,14 +97,18 @@ func LoadConfigs() {
|
||||
|
||||
func getEngine() (*xorm.Engine, error) {
|
||||
cnnstr := ""
|
||||
var Param string = "?"
|
||||
if strings.Contains(DbCfg.Name,Param) {
|
||||
Param="&"
|
||||
}
|
||||
switch DbCfg.Type {
|
||||
case "mysql":
|
||||
if DbCfg.Host[0] == '/' { // looks like a unix socket
|
||||
cnnstr = fmt.Sprintf("%s:%s@unix(%s)/%s?charset=utf8&parseTime=true",
|
||||
DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name)
|
||||
cnnstr = fmt.Sprintf("%s:%s@unix(%s)/%s%scharset=utf8&parseTime=true",
|
||||
DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name, Param)
|
||||
} else {
|
||||
cnnstr = fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=true",
|
||||
DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name)
|
||||
cnnstr = fmt.Sprintf("%s:%s@tcp(%s)/%s%scharset=utf8&parseTime=true",
|
||||
DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name, Param)
|
||||
}
|
||||
case "postgres":
|
||||
var host, port = "127.0.0.1", "5432"
|
||||
@@ -115,8 +119,8 @@ func getEngine() (*xorm.Engine, error) {
|
||||
if len(fields) > 1 && len(strings.TrimSpace(fields[1])) > 0 {
|
||||
port = fields[1]
|
||||
}
|
||||
cnnstr = fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=%s",
|
||||
url.QueryEscape(DbCfg.User), url.QueryEscape(DbCfg.Passwd), host, port, DbCfg.Name, DbCfg.SSLMode)
|
||||
cnnstr = fmt.Sprintf("postgres://%s:%s@%s:%s/%s%ssslmode=%s",
|
||||
url.QueryEscape(DbCfg.User), url.QueryEscape(DbCfg.Passwd), host, port, DbCfg.Name, Param, DbCfg.SSLMode)
|
||||
case "sqlite3":
|
||||
if !EnableSQLite3 {
|
||||
return nil, fmt.Errorf("Unknown database type: %s", DbCfg.Type)
|
||||
|
||||
624
models/org.go
624
models/org.go
@@ -58,7 +58,7 @@ func (org *User) GetTeams() error {
|
||||
|
||||
// GetMembers returns all members of organization.
|
||||
func (org *User) GetMembers() error {
|
||||
ous, err := GetOrgUsersByOrgId(org.Id)
|
||||
ous, err := GetOrgUsersByOrgID(org.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -306,10 +306,10 @@ func GetOrgUsersByUserID(uid int64, all bool) ([]*OrgUser, error) {
|
||||
return ous, err
|
||||
}
|
||||
|
||||
// GetOrgUsersByOrgId returns all organization-user relations by organization ID.
|
||||
func GetOrgUsersByOrgId(orgId int64) ([]*OrgUser, error) {
|
||||
// GetOrgUsersByOrgID returns all organization-user relations by organization ID.
|
||||
func GetOrgUsersByOrgID(orgID int64) ([]*OrgUser, error) {
|
||||
ous := make([]*OrgUser, 0, 10)
|
||||
err := x.Where("org_id=?", orgId).Find(&ous)
|
||||
err := x.Where("org_id=?", orgID).Find(&ous)
|
||||
return ous, err
|
||||
}
|
||||
|
||||
@@ -426,618 +426,6 @@ func RemoveOrgUser(orgId, uid int64) error {
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// ___________
|
||||
// \__ ___/___ _____ _____
|
||||
// | |_/ __ \\__ \ / \
|
||||
// | |\ ___/ / __ \| Y Y \
|
||||
// |____| \___ >____ /__|_| /
|
||||
// \/ \/ \/
|
||||
|
||||
const OWNER_TEAM = "Owners"
|
||||
|
||||
// Team represents a organization team.
|
||||
type Team struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
OrgID int64 `xorm:"INDEX"`
|
||||
LowerName string
|
||||
Name string
|
||||
Description string
|
||||
Authorize AccessMode
|
||||
Repos []*Repository `xorm:"-"`
|
||||
Members []*User `xorm:"-"`
|
||||
NumRepos int
|
||||
NumMembers int
|
||||
}
|
||||
|
||||
// IsOwnerTeam returns true if team is owner team.
|
||||
func (t *Team) IsOwnerTeam() bool {
|
||||
return t.Name == OWNER_TEAM
|
||||
}
|
||||
|
||||
// IsTeamMember returns true if given user is a member of team.
|
||||
func (t *Team) IsMember(uid int64) bool {
|
||||
return IsTeamMember(t.OrgID, t.ID, uid)
|
||||
}
|
||||
|
||||
func (t *Team) getRepositories(e Engine) (err error) {
|
||||
teamRepos := make([]*TeamRepo, 0, t.NumRepos)
|
||||
if err = x.Where("team_id=?", t.ID).Find(&teamRepos); err != nil {
|
||||
return fmt.Errorf("get team-repos: %v", err)
|
||||
}
|
||||
|
||||
t.Repos = make([]*Repository, 0, len(teamRepos))
|
||||
for i := range teamRepos {
|
||||
repo, err := getRepositoryByID(e, teamRepos[i].RepoID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getRepositoryById(%d): %v", teamRepos[i].RepoID, err)
|
||||
}
|
||||
t.Repos = append(t.Repos, repo)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRepositories returns all repositories in team of organization.
|
||||
func (t *Team) GetRepositories() error {
|
||||
return t.getRepositories(x)
|
||||
}
|
||||
|
||||
func (t *Team) getMembers(e Engine) (err error) {
|
||||
t.Members, err = getTeamMembers(e, t.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetMembers returns all members in team of organization.
|
||||
func (t *Team) GetMembers() (err error) {
|
||||
return t.getMembers(x)
|
||||
}
|
||||
|
||||
// AddMember adds new member to team of organization.
|
||||
func (t *Team) AddMember(uid int64) error {
|
||||
return AddTeamMember(t.OrgID, t.ID, uid)
|
||||
}
|
||||
|
||||
// RemoveMember removes member from team of organization.
|
||||
func (t *Team) RemoveMember(uid int64) error {
|
||||
return RemoveTeamMember(t.OrgID, t.ID, uid)
|
||||
}
|
||||
|
||||
func (t *Team) hasRepository(e Engine, repoID int64) bool {
|
||||
return hasTeamRepo(e, t.OrgID, t.ID, repoID)
|
||||
}
|
||||
|
||||
// HasRepository returns true if given repository belong to team.
|
||||
func (t *Team) HasRepository(repoID int64) bool {
|
||||
return t.hasRepository(x, repoID)
|
||||
}
|
||||
|
||||
func (t *Team) addRepository(e Engine, repo *Repository) (err error) {
|
||||
if err = addTeamRepo(e, t.OrgID, t.ID, repo.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.NumRepos++
|
||||
if _, err = e.Id(t.ID).AllCols().Update(t); err != nil {
|
||||
return fmt.Errorf("update team: %v", err)
|
||||
}
|
||||
|
||||
if err = repo.recalculateTeamAccesses(e, 0); err != nil {
|
||||
return fmt.Errorf("recalculateAccesses: %v", err)
|
||||
}
|
||||
|
||||
if err = t.getMembers(e); err != nil {
|
||||
return fmt.Errorf("getMembers: %v", err)
|
||||
}
|
||||
for _, u := range t.Members {
|
||||
if err = watchRepo(e, u.Id, repo.ID, true); err != nil {
|
||||
return fmt.Errorf("watchRepo: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddRepository adds new repository to team of organization.
|
||||
func (t *Team) AddRepository(repo *Repository) (err error) {
|
||||
if repo.OwnerID != t.OrgID {
|
||||
return errors.New("Repository does not belong to organization")
|
||||
} else if t.HasRepository(repo.ID) {
|
||||
return nil
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = t.addRepository(sess, repo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
func (t *Team) removeRepository(e Engine, repo *Repository, recalculate bool) (err error) {
|
||||
if err = removeTeamRepo(e, t.ID, repo.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.NumRepos--
|
||||
if _, err = e.Id(t.ID).AllCols().Update(t); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Don't need to recalculate when delete a repository from organization.
|
||||
if recalculate {
|
||||
if err = repo.recalculateTeamAccesses(e, t.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err = t.getMembers(e); err != nil {
|
||||
return fmt.Errorf("get team members: %v", err)
|
||||
}
|
||||
for _, u := range t.Members {
|
||||
has, err := hasAccess(e, u, repo, ACCESS_MODE_READ)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if has {
|
||||
continue
|
||||
}
|
||||
|
||||
if err = watchRepo(e, u.Id, repo.ID, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveRepository removes repository from team of organization.
|
||||
func (t *Team) RemoveRepository(repoID int64) error {
|
||||
if !t.HasRepository(repoID) {
|
||||
return nil
|
||||
}
|
||||
|
||||
repo, err := GetRepositoryByID(repoID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = t.removeRepository(sess, repo, true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// NewTeam creates a record of new team.
|
||||
// It's caller's responsibility to assign organization ID.
|
||||
func NewTeam(t *Team) error {
|
||||
if len(t.Name) == 0 {
|
||||
return errors.New("empty team name")
|
||||
}
|
||||
|
||||
has, err := x.Id(t.OrgID).Get(new(User))
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
return ErrOrgNotExist
|
||||
}
|
||||
|
||||
t.LowerName = strings.ToLower(t.Name)
|
||||
has, err = x.Where("org_id=?", t.OrgID).And("lower_name=?", t.LowerName).Get(new(Team))
|
||||
if err != nil {
|
||||
return err
|
||||
} else if has {
|
||||
return ErrTeamAlreadyExist{t.OrgID, t.LowerName}
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.Insert(t); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
// Update organization number of teams.
|
||||
if _, err = sess.Exec("UPDATE `user` SET num_teams=num_teams+1 WHERE id = ?", t.OrgID); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
func getTeam(e Engine, orgId int64, name string) (*Team, error) {
|
||||
t := &Team{
|
||||
OrgID: orgId,
|
||||
LowerName: strings.ToLower(name),
|
||||
}
|
||||
has, err := e.Get(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrTeamNotExist
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// GetTeam returns team by given team name and organization.
|
||||
func GetTeam(orgId int64, name string) (*Team, error) {
|
||||
return getTeam(x, orgId, name)
|
||||
}
|
||||
|
||||
func getTeamById(e Engine, teamId int64) (*Team, error) {
|
||||
t := new(Team)
|
||||
has, err := e.Id(teamId).Get(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrTeamNotExist
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// GetTeamById returns team by given ID.
|
||||
func GetTeamById(teamId int64) (*Team, error) {
|
||||
return getTeamById(x, teamId)
|
||||
}
|
||||
|
||||
// UpdateTeam updates information of team.
|
||||
func UpdateTeam(t *Team, authChanged bool) (err error) {
|
||||
if len(t.Name) == 0 {
|
||||
return errors.New("empty team name")
|
||||
}
|
||||
|
||||
if len(t.Description) > 255 {
|
||||
t.Description = t.Description[:255]
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.LowerName = strings.ToLower(t.Name)
|
||||
has, err := x.Where("org_id=?", t.OrgID).And("lower_name=?", t.LowerName).And("id!=?", t.ID).Get(new(Team))
|
||||
if err != nil {
|
||||
return err
|
||||
} else if has {
|
||||
return ErrTeamAlreadyExist{t.OrgID, t.LowerName}
|
||||
}
|
||||
|
||||
if _, err = sess.Id(t.ID).AllCols().Update(t); err != nil {
|
||||
return fmt.Errorf("update: %v", err)
|
||||
}
|
||||
|
||||
// Update access for team members if needed.
|
||||
if authChanged {
|
||||
if err = t.getRepositories(sess); err != nil {
|
||||
return fmt.Errorf("getRepositories:%v", err)
|
||||
}
|
||||
|
||||
for _, repo := range t.Repos {
|
||||
if err = repo.recalculateTeamAccesses(sess, 0); err != nil {
|
||||
return fmt.Errorf("recalculateTeamAccesses: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// DeleteTeam deletes given team.
|
||||
// It's caller's responsibility to assign organization ID.
|
||||
func DeleteTeam(t *Team) error {
|
||||
if err := t.GetRepositories(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get organization.
|
||||
org, err := GetUserByID(t.OrgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete all accesses.
|
||||
for _, repo := range t.Repos {
|
||||
if err = repo.recalculateTeamAccesses(sess, t.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Delete team-user.
|
||||
if _, err = sess.Where("org_id=?", org.Id).Where("team_id=?", t.ID).Delete(new(TeamUser)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete team.
|
||||
if _, err = sess.Id(t.ID).Delete(new(Team)); err != nil {
|
||||
return err
|
||||
}
|
||||
// Update organization number of teams.
|
||||
if _, err = sess.Exec("UPDATE `user` SET num_teams=num_teams-1 WHERE id=?", t.OrgID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// ___________ ____ ___
|
||||
// \__ ___/___ _____ _____ | | \______ ___________
|
||||
// | |_/ __ \\__ \ / \| | / ___// __ \_ __ \
|
||||
// | |\ ___/ / __ \| Y Y \ | /\___ \\ ___/| | \/
|
||||
// |____| \___ >____ /__|_| /______//____ >\___ >__|
|
||||
// \/ \/ \/ \/ \/
|
||||
|
||||
// TeamUser represents an team-user relation.
|
||||
type TeamUser struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
OrgID int64 `xorm:"INDEX"`
|
||||
TeamID int64 `xorm:"UNIQUE(s)"`
|
||||
Uid int64 `xorm:"UNIQUE(s)"`
|
||||
}
|
||||
|
||||
func isTeamMember(e Engine, orgID, teamID, uid int64) bool {
|
||||
has, _ := e.Where("org_id=?", orgID).And("team_id=?", teamID).And("uid=?", uid).Get(new(TeamUser))
|
||||
return has
|
||||
}
|
||||
|
||||
// IsTeamMember returns true if given user is a member of team.
|
||||
func IsTeamMember(orgID, teamID, uid int64) bool {
|
||||
return isTeamMember(x, orgID, teamID, uid)
|
||||
}
|
||||
|
||||
func getTeamMembers(e Engine, teamID int64) (_ []*User, err error) {
|
||||
teamUsers := make([]*TeamUser, 0, 10)
|
||||
if err = e.Where("team_id=?", teamID).Find(&teamUsers); err != nil {
|
||||
return nil, fmt.Errorf("get team-users: %v", err)
|
||||
}
|
||||
members := make([]*User, 0, len(teamUsers))
|
||||
for i := range teamUsers {
|
||||
member := new(User)
|
||||
if _, err = e.Id(teamUsers[i].Uid).Get(member); err != nil {
|
||||
return nil, fmt.Errorf("get user '%d': %v", teamUsers[i].Uid, err)
|
||||
}
|
||||
members = append(members, member)
|
||||
}
|
||||
return members, nil
|
||||
}
|
||||
|
||||
// GetTeamMembers returns all members in given team of organization.
|
||||
func GetTeamMembers(teamID int64) ([]*User, error) {
|
||||
return getTeamMembers(x, teamID)
|
||||
}
|
||||
|
||||
func getUserTeams(e Engine, orgId, uid int64) ([]*Team, error) {
|
||||
tus := make([]*TeamUser, 0, 5)
|
||||
if err := e.Where("uid=?", uid).And("org_id=?", orgId).Find(&tus); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ts := make([]*Team, len(tus))
|
||||
for i, tu := range tus {
|
||||
t := new(Team)
|
||||
has, err := e.Id(tu.TeamID).Get(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrTeamNotExist
|
||||
}
|
||||
ts[i] = t
|
||||
}
|
||||
return ts, nil
|
||||
}
|
||||
|
||||
// GetUserTeams returns all teams that user belongs to in given organization.
|
||||
func GetUserTeams(orgId, uid int64) ([]*Team, error) {
|
||||
return getUserTeams(x, orgId, uid)
|
||||
}
|
||||
|
||||
// AddTeamMember adds new member to given team of given organization.
|
||||
func AddTeamMember(orgId, teamId, uid int64) error {
|
||||
if IsTeamMember(orgId, teamId, uid) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := AddOrgUser(orgId, uid); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get team and its repositories.
|
||||
t, err := GetTeamById(teamId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.NumMembers++
|
||||
|
||||
if err = t.GetRepositories(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tu := &TeamUser{
|
||||
Uid: uid,
|
||||
OrgID: orgId,
|
||||
TeamID: teamId,
|
||||
}
|
||||
if _, err = sess.Insert(tu); err != nil {
|
||||
return err
|
||||
} else if _, err = sess.Id(t.ID).Update(t); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Give access to team repositories.
|
||||
for _, repo := range t.Repos {
|
||||
if err = repo.recalculateTeamAccesses(sess, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// We make sure it exists before.
|
||||
ou := new(OrgUser)
|
||||
if _, err = sess.Where("uid=?", uid).And("org_id=?", orgId).Get(ou); err != nil {
|
||||
return err
|
||||
}
|
||||
ou.NumTeams++
|
||||
if t.IsOwnerTeam() {
|
||||
ou.IsOwner = true
|
||||
}
|
||||
if _, err = sess.Id(ou.ID).AllCols().Update(ou); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
func removeTeamMember(e Engine, orgId, teamId, uid int64) error {
|
||||
if !isTeamMember(e, orgId, teamId, uid) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get team and its repositories.
|
||||
t, err := getTeamById(e, teamId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check if the user to delete is the last member in owner team.
|
||||
if t.IsOwnerTeam() && t.NumMembers == 1 {
|
||||
return ErrLastOrgOwner{UID: uid}
|
||||
}
|
||||
|
||||
t.NumMembers--
|
||||
|
||||
if err = t.getRepositories(e); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get organization.
|
||||
org, err := getUserByID(e, orgId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tu := &TeamUser{
|
||||
Uid: uid,
|
||||
OrgID: orgId,
|
||||
TeamID: teamId,
|
||||
}
|
||||
if _, err := e.Delete(tu); err != nil {
|
||||
return err
|
||||
} else if _, err = e.Id(t.ID).AllCols().Update(t); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete access to team repositories.
|
||||
for _, repo := range t.Repos {
|
||||
if err = repo.recalculateTeamAccesses(e, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// This must exist.
|
||||
ou := new(OrgUser)
|
||||
_, err = e.Where("uid=?", uid).And("org_id=?", org.Id).Get(ou)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ou.NumTeams--
|
||||
if t.IsOwnerTeam() {
|
||||
ou.IsOwner = false
|
||||
}
|
||||
if _, err = e.Id(ou.ID).AllCols().Update(ou); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveTeamMember removes member from given team of given organization.
|
||||
func RemoveTeamMember(orgId, teamId, uid int64) error {
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := removeTeamMember(sess, orgId, teamId, uid); err != nil {
|
||||
return err
|
||||
}
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// ___________ __________
|
||||
// \__ ___/___ _____ _____\______ \ ____ ______ ____
|
||||
// | |_/ __ \\__ \ / \| _// __ \\____ \ / _ \
|
||||
// | |\ ___/ / __ \| Y Y \ | \ ___/| |_> > <_> )
|
||||
// |____| \___ >____ /__|_| /____|_ /\___ > __/ \____/
|
||||
// \/ \/ \/ \/ \/|__|
|
||||
|
||||
// TeamRepo represents an team-repository relation.
|
||||
type TeamRepo struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
OrgID int64 `xorm:"INDEX"`
|
||||
TeamID int64 `xorm:"UNIQUE(s)"`
|
||||
RepoID int64 `xorm:"UNIQUE(s)"`
|
||||
}
|
||||
|
||||
func hasTeamRepo(e Engine, orgID, teamID, repoID int64) bool {
|
||||
has, _ := e.Where("org_id=?", orgID).And("team_id=?", teamID).And("repo_id=?", repoID).Get(new(TeamRepo))
|
||||
return has
|
||||
}
|
||||
|
||||
// HasTeamRepo returns true if given repository belongs to team.
|
||||
func HasTeamRepo(orgID, teamID, repoID int64) bool {
|
||||
return hasTeamRepo(x, orgID, teamID, repoID)
|
||||
}
|
||||
|
||||
func addTeamRepo(e Engine, orgID, teamID, repoID int64) error {
|
||||
_, err := e.InsertOne(&TeamRepo{
|
||||
OrgID: orgID,
|
||||
TeamID: teamID,
|
||||
RepoID: repoID,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// AddTeamRepo adds new repository relation to team.
|
||||
func AddTeamRepo(orgID, teamID, repoID int64) error {
|
||||
return addTeamRepo(x, orgID, teamID, repoID)
|
||||
}
|
||||
|
||||
func removeTeamRepo(e Engine, teamID, repoID int64) error {
|
||||
_, err := e.Delete(&TeamRepo{
|
||||
TeamID: teamID,
|
||||
RepoID: repoID,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// RemoveTeamRepo deletes repository relation to team.
|
||||
func RemoveTeamRepo(teamID, repoID int64) error {
|
||||
return removeTeamRepo(x, teamID, repoID)
|
||||
}
|
||||
|
||||
func removeOrgRepo(e Engine, orgID, repoID int64) error {
|
||||
_, err := e.Delete(&TeamRepo{
|
||||
OrgID: orgID,
|
||||
@@ -1055,7 +443,7 @@ func RemoveOrgRepo(orgID, repoID int64) error {
|
||||
// that the user with the given userID has access to.
|
||||
func (org *User) GetUserRepositories(userID int64) (err error) {
|
||||
teams := make([]*Team, 0, org.NumTeams)
|
||||
if err = x.Sql(`SELECT team.id FROM team
|
||||
if err = x.Sql(`SELECT team.id FROM team
|
||||
INNER JOIN team_user ON team_user.team_id = team.id
|
||||
WHERE team_user.org_id = ? AND team_user.uid = ?`, org.Id, userID).Find(&teams); err != nil {
|
||||
return fmt.Errorf("get teams: %v", err)
|
||||
@@ -1096,6 +484,8 @@ WHERE team_user.org_id = ? AND team_user.uid = ?`,
|
||||
return fmt.Errorf("get teams: %v", err)
|
||||
}
|
||||
|
||||
org.Teams = teams
|
||||
|
||||
// FIXME: should I change this value inside method,
|
||||
// or only in location of caller where it's really needed?
|
||||
org.NumTeams = len(org.Teams)
|
||||
|
||||
618
models/org_team.go
Normal file
618
models/org_team.go
Normal file
@@ -0,0 +1,618 @@
|
||||
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const OWNER_TEAM = "Owners"
|
||||
|
||||
// Team represents a organization team.
|
||||
type Team struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
OrgID int64 `xorm:"INDEX"`
|
||||
LowerName string
|
||||
Name string
|
||||
Description string
|
||||
Authorize AccessMode
|
||||
Repos []*Repository `xorm:"-"`
|
||||
Members []*User `xorm:"-"`
|
||||
NumRepos int
|
||||
NumMembers int
|
||||
}
|
||||
|
||||
// IsOwnerTeam returns true if team is owner team.
|
||||
func (t *Team) IsOwnerTeam() bool {
|
||||
return t.Name == OWNER_TEAM
|
||||
}
|
||||
|
||||
// IsTeamMember returns true if given user is a member of team.
|
||||
func (t *Team) IsMember(uid int64) bool {
|
||||
return IsTeamMember(t.OrgID, t.ID, uid)
|
||||
}
|
||||
|
||||
func (t *Team) getRepositories(e Engine) (err error) {
|
||||
teamRepos := make([]*TeamRepo, 0, t.NumRepos)
|
||||
if err = x.Where("team_id=?", t.ID).Find(&teamRepos); err != nil {
|
||||
return fmt.Errorf("get team-repos: %v", err)
|
||||
}
|
||||
|
||||
t.Repos = make([]*Repository, 0, len(teamRepos))
|
||||
for i := range teamRepos {
|
||||
repo, err := getRepositoryByID(e, teamRepos[i].RepoID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getRepositoryById(%d): %v", teamRepos[i].RepoID, err)
|
||||
}
|
||||
t.Repos = append(t.Repos, repo)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRepositories returns all repositories in team of organization.
|
||||
func (t *Team) GetRepositories() error {
|
||||
return t.getRepositories(x)
|
||||
}
|
||||
|
||||
func (t *Team) getMembers(e Engine) (err error) {
|
||||
t.Members, err = getTeamMembers(e, t.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetMembers returns all members in team of organization.
|
||||
func (t *Team) GetMembers() (err error) {
|
||||
return t.getMembers(x)
|
||||
}
|
||||
|
||||
// AddMember adds new membership of the team to the organization,
|
||||
// the user will have membership to the organization automatically when needed.
|
||||
func (t *Team) AddMember(uid int64) error {
|
||||
return AddTeamMember(t.OrgID, t.ID, uid)
|
||||
}
|
||||
|
||||
// RemoveMember removes member from team of organization.
|
||||
func (t *Team) RemoveMember(uid int64) error {
|
||||
return RemoveTeamMember(t.OrgID, t.ID, uid)
|
||||
}
|
||||
|
||||
func (t *Team) hasRepository(e Engine, repoID int64) bool {
|
||||
return hasTeamRepo(e, t.OrgID, t.ID, repoID)
|
||||
}
|
||||
|
||||
// HasRepository returns true if given repository belong to team.
|
||||
func (t *Team) HasRepository(repoID int64) bool {
|
||||
return t.hasRepository(x, repoID)
|
||||
}
|
||||
|
||||
func (t *Team) addRepository(e Engine, repo *Repository) (err error) {
|
||||
if err = addTeamRepo(e, t.OrgID, t.ID, repo.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.NumRepos++
|
||||
if _, err = e.Id(t.ID).AllCols().Update(t); err != nil {
|
||||
return fmt.Errorf("update team: %v", err)
|
||||
}
|
||||
|
||||
if err = repo.recalculateTeamAccesses(e, 0); err != nil {
|
||||
return fmt.Errorf("recalculateAccesses: %v", err)
|
||||
}
|
||||
|
||||
if err = t.getMembers(e); err != nil {
|
||||
return fmt.Errorf("getMembers: %v", err)
|
||||
}
|
||||
for _, u := range t.Members {
|
||||
if err = watchRepo(e, u.Id, repo.ID, true); err != nil {
|
||||
return fmt.Errorf("watchRepo: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddRepository adds new repository to team of organization.
|
||||
func (t *Team) AddRepository(repo *Repository) (err error) {
|
||||
if repo.OwnerID != t.OrgID {
|
||||
return errors.New("Repository does not belong to organization")
|
||||
} else if t.HasRepository(repo.ID) {
|
||||
return nil
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = t.addRepository(sess, repo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
func (t *Team) removeRepository(e Engine, repo *Repository, recalculate bool) (err error) {
|
||||
if err = removeTeamRepo(e, t.ID, repo.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.NumRepos--
|
||||
if _, err = e.Id(t.ID).AllCols().Update(t); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Don't need to recalculate when delete a repository from organization.
|
||||
if recalculate {
|
||||
if err = repo.recalculateTeamAccesses(e, t.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err = t.getMembers(e); err != nil {
|
||||
return fmt.Errorf("get team members: %v", err)
|
||||
}
|
||||
for _, u := range t.Members {
|
||||
has, err := hasAccess(e, u, repo, ACCESS_MODE_READ)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if has {
|
||||
continue
|
||||
}
|
||||
|
||||
if err = watchRepo(e, u.Id, repo.ID, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveRepository removes repository from team of organization.
|
||||
func (t *Team) RemoveRepository(repoID int64) error {
|
||||
if !t.HasRepository(repoID) {
|
||||
return nil
|
||||
}
|
||||
|
||||
repo, err := GetRepositoryByID(repoID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = t.removeRepository(sess, repo, true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// NewTeam creates a record of new team.
|
||||
// It's caller's responsibility to assign organization ID.
|
||||
func NewTeam(t *Team) error {
|
||||
if len(t.Name) == 0 {
|
||||
return errors.New("empty team name")
|
||||
}
|
||||
|
||||
has, err := x.Id(t.OrgID).Get(new(User))
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
return ErrOrgNotExist
|
||||
}
|
||||
|
||||
t.LowerName = strings.ToLower(t.Name)
|
||||
has, err = x.Where("org_id=?", t.OrgID).And("lower_name=?", t.LowerName).Get(new(Team))
|
||||
if err != nil {
|
||||
return err
|
||||
} else if has {
|
||||
return ErrTeamAlreadyExist{t.OrgID, t.LowerName}
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.Insert(t); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
// Update organization number of teams.
|
||||
if _, err = sess.Exec("UPDATE `user` SET num_teams=num_teams+1 WHERE id = ?", t.OrgID); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
func getTeam(e Engine, orgId int64, name string) (*Team, error) {
|
||||
t := &Team{
|
||||
OrgID: orgId,
|
||||
LowerName: strings.ToLower(name),
|
||||
}
|
||||
has, err := e.Get(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrTeamNotExist
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// GetTeam returns team by given team name and organization.
|
||||
func GetTeam(orgId int64, name string) (*Team, error) {
|
||||
return getTeam(x, orgId, name)
|
||||
}
|
||||
|
||||
func getTeamByID(e Engine, teamId int64) (*Team, error) {
|
||||
t := new(Team)
|
||||
has, err := e.Id(teamId).Get(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrTeamNotExist
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// GetTeamByID returns team by given ID.
|
||||
func GetTeamByID(teamId int64) (*Team, error) {
|
||||
return getTeamByID(x, teamId)
|
||||
}
|
||||
|
||||
// UpdateTeam updates information of team.
|
||||
func UpdateTeam(t *Team, authChanged bool) (err error) {
|
||||
if len(t.Name) == 0 {
|
||||
return errors.New("empty team name")
|
||||
}
|
||||
|
||||
if len(t.Description) > 255 {
|
||||
t.Description = t.Description[:255]
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.LowerName = strings.ToLower(t.Name)
|
||||
has, err := x.Where("org_id=?", t.OrgID).And("lower_name=?", t.LowerName).And("id!=?", t.ID).Get(new(Team))
|
||||
if err != nil {
|
||||
return err
|
||||
} else if has {
|
||||
return ErrTeamAlreadyExist{t.OrgID, t.LowerName}
|
||||
}
|
||||
|
||||
if _, err = sess.Id(t.ID).AllCols().Update(t); err != nil {
|
||||
return fmt.Errorf("update: %v", err)
|
||||
}
|
||||
|
||||
// Update access for team members if needed.
|
||||
if authChanged {
|
||||
if err = t.getRepositories(sess); err != nil {
|
||||
return fmt.Errorf("getRepositories:%v", err)
|
||||
}
|
||||
|
||||
for _, repo := range t.Repos {
|
||||
if err = repo.recalculateTeamAccesses(sess, 0); err != nil {
|
||||
return fmt.Errorf("recalculateTeamAccesses: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// DeleteTeam deletes given team.
|
||||
// It's caller's responsibility to assign organization ID.
|
||||
func DeleteTeam(t *Team) error {
|
||||
if err := t.GetRepositories(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get organization.
|
||||
org, err := GetUserByID(t.OrgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete all accesses.
|
||||
for _, repo := range t.Repos {
|
||||
if err = repo.recalculateTeamAccesses(sess, t.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Delete team-user.
|
||||
if _, err = sess.Where("org_id=?", org.Id).Where("team_id=?", t.ID).Delete(new(TeamUser)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete team.
|
||||
if _, err = sess.Id(t.ID).Delete(new(Team)); err != nil {
|
||||
return err
|
||||
}
|
||||
// Update organization number of teams.
|
||||
if _, err = sess.Exec("UPDATE `user` SET num_teams=num_teams-1 WHERE id=?", t.OrgID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// ___________ ____ ___
|
||||
// \__ ___/___ _____ _____ | | \______ ___________
|
||||
// | |_/ __ \\__ \ / \| | / ___// __ \_ __ \
|
||||
// | |\ ___/ / __ \| Y Y \ | /\___ \\ ___/| | \/
|
||||
// |____| \___ >____ /__|_| /______//____ >\___ >__|
|
||||
// \/ \/ \/ \/ \/
|
||||
|
||||
// TeamUser represents an team-user relation.
|
||||
type TeamUser struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
OrgID int64 `xorm:"INDEX"`
|
||||
TeamID int64 `xorm:"UNIQUE(s)"`
|
||||
Uid int64 `xorm:"UNIQUE(s)"`
|
||||
}
|
||||
|
||||
func isTeamMember(e Engine, orgID, teamID, uid int64) bool {
|
||||
has, _ := e.Where("org_id=?", orgID).And("team_id=?", teamID).And("uid=?", uid).Get(new(TeamUser))
|
||||
return has
|
||||
}
|
||||
|
||||
// IsTeamMember returns true if given user is a member of team.
|
||||
func IsTeamMember(orgID, teamID, uid int64) bool {
|
||||
return isTeamMember(x, orgID, teamID, uid)
|
||||
}
|
||||
|
||||
func getTeamMembers(e Engine, teamID int64) (_ []*User, err error) {
|
||||
teamUsers := make([]*TeamUser, 0, 10)
|
||||
if err = e.Where("team_id=?", teamID).Find(&teamUsers); err != nil {
|
||||
return nil, fmt.Errorf("get team-users: %v", err)
|
||||
}
|
||||
members := make([]*User, 0, len(teamUsers))
|
||||
for i := range teamUsers {
|
||||
member := new(User)
|
||||
if _, err = e.Id(teamUsers[i].Uid).Get(member); err != nil {
|
||||
return nil, fmt.Errorf("get user '%d': %v", teamUsers[i].Uid, err)
|
||||
}
|
||||
members = append(members, member)
|
||||
}
|
||||
return members, nil
|
||||
}
|
||||
|
||||
// GetTeamMembers returns all members in given team of organization.
|
||||
func GetTeamMembers(teamID int64) ([]*User, error) {
|
||||
return getTeamMembers(x, teamID)
|
||||
}
|
||||
|
||||
func getUserTeams(e Engine, orgId, uid int64) ([]*Team, error) {
|
||||
tus := make([]*TeamUser, 0, 5)
|
||||
if err := e.Where("uid=?", uid).And("org_id=?", orgId).Find(&tus); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ts := make([]*Team, len(tus))
|
||||
for i, tu := range tus {
|
||||
t := new(Team)
|
||||
has, err := e.Id(tu.TeamID).Get(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrTeamNotExist
|
||||
}
|
||||
ts[i] = t
|
||||
}
|
||||
return ts, nil
|
||||
}
|
||||
|
||||
// GetUserTeams returns all teams that user belongs to in given organization.
|
||||
func GetUserTeams(orgId, uid int64) ([]*Team, error) {
|
||||
return getUserTeams(x, orgId, uid)
|
||||
}
|
||||
|
||||
// AddTeamMember adds new membership of given team to given organization,
|
||||
// the user will have membership to given organization automatically when needed.
|
||||
func AddTeamMember(orgID, teamID, uid int64) error {
|
||||
if IsTeamMember(orgID, teamID, uid) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := AddOrgUser(orgID, uid); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get team and its repositories.
|
||||
t, err := GetTeamByID(teamID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.NumMembers++
|
||||
|
||||
if err = t.GetRepositories(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tu := &TeamUser{
|
||||
Uid: uid,
|
||||
OrgID: orgID,
|
||||
TeamID: teamID,
|
||||
}
|
||||
if _, err = sess.Insert(tu); err != nil {
|
||||
return err
|
||||
} else if _, err = sess.Id(t.ID).Update(t); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Give access to team repositories.
|
||||
for _, repo := range t.Repos {
|
||||
if err = repo.recalculateTeamAccesses(sess, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// We make sure it exists before.
|
||||
ou := new(OrgUser)
|
||||
if _, err = sess.Where("uid = ?", uid).And("org_id = ?", orgID).Get(ou); err != nil {
|
||||
return err
|
||||
}
|
||||
ou.NumTeams++
|
||||
if t.IsOwnerTeam() {
|
||||
ou.IsOwner = true
|
||||
}
|
||||
if _, err = sess.Id(ou.ID).AllCols().Update(ou); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
func removeTeamMember(e Engine, orgID, teamID, uid int64) error {
|
||||
if !isTeamMember(e, orgID, teamID, uid) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get team and its repositories.
|
||||
t, err := getTeamByID(e, teamID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check if the user to delete is the last member in owner team.
|
||||
if t.IsOwnerTeam() && t.NumMembers == 1 {
|
||||
return ErrLastOrgOwner{UID: uid}
|
||||
}
|
||||
|
||||
t.NumMembers--
|
||||
|
||||
if err = t.getRepositories(e); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get organization.
|
||||
org, err := getUserByID(e, orgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tu := &TeamUser{
|
||||
Uid: uid,
|
||||
OrgID: orgID,
|
||||
TeamID: teamID,
|
||||
}
|
||||
if _, err := e.Delete(tu); err != nil {
|
||||
return err
|
||||
} else if _, err = e.Id(t.ID).AllCols().Update(t); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete access to team repositories.
|
||||
for _, repo := range t.Repos {
|
||||
if err = repo.recalculateTeamAccesses(e, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// This must exist.
|
||||
ou := new(OrgUser)
|
||||
_, err = e.Where("uid = ?", uid).And("org_id = ?", org.Id).Get(ou)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ou.NumTeams--
|
||||
if t.IsOwnerTeam() {
|
||||
ou.IsOwner = false
|
||||
}
|
||||
if _, err = e.Id(ou.ID).AllCols().Update(ou); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveTeamMember removes member from given team of given organization.
|
||||
func RemoveTeamMember(orgID, teamID, uid int64) error {
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := removeTeamMember(sess, orgID, teamID, uid); err != nil {
|
||||
return err
|
||||
}
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// ___________ __________
|
||||
// \__ ___/___ _____ _____\______ \ ____ ______ ____
|
||||
// | |_/ __ \\__ \ / \| _// __ \\____ \ / _ \
|
||||
// | |\ ___/ / __ \| Y Y \ | \ ___/| |_> > <_> )
|
||||
// |____| \___ >____ /__|_| /____|_ /\___ > __/ \____/
|
||||
// \/ \/ \/ \/ \/|__|
|
||||
|
||||
// TeamRepo represents an team-repository relation.
|
||||
type TeamRepo struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
OrgID int64 `xorm:"INDEX"`
|
||||
TeamID int64 `xorm:"UNIQUE(s)"`
|
||||
RepoID int64 `xorm:"UNIQUE(s)"`
|
||||
}
|
||||
|
||||
func hasTeamRepo(e Engine, orgID, teamID, repoID int64) bool {
|
||||
has, _ := e.Where("org_id=?", orgID).And("team_id=?", teamID).And("repo_id=?", repoID).Get(new(TeamRepo))
|
||||
return has
|
||||
}
|
||||
|
||||
// HasTeamRepo returns true if given repository belongs to team.
|
||||
func HasTeamRepo(orgID, teamID, repoID int64) bool {
|
||||
return hasTeamRepo(x, orgID, teamID, repoID)
|
||||
}
|
||||
|
||||
func addTeamRepo(e Engine, orgID, teamID, repoID int64) error {
|
||||
_, err := e.InsertOne(&TeamRepo{
|
||||
OrgID: orgID,
|
||||
TeamID: teamID,
|
||||
RepoID: repoID,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// AddTeamRepo adds new repository relation to team.
|
||||
func AddTeamRepo(orgID, teamID, repoID int64) error {
|
||||
return addTeamRepo(x, orgID, teamID, repoID)
|
||||
}
|
||||
|
||||
func removeTeamRepo(e Engine, teamID, repoID int64) error {
|
||||
_, err := e.Delete(&TeamRepo{
|
||||
TeamID: teamID,
|
||||
RepoID: repoID,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// RemoveTeamRepo deletes repository relation to team.
|
||||
func RemoveTeamRepo(teamID, repoID int64) error {
|
||||
return removeTeamRepo(x, teamID, repoID)
|
||||
}
|
||||
@@ -236,7 +236,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error
|
||||
Before: pr.MergeBase,
|
||||
After: pr.MergedCommitID,
|
||||
CompareUrl: setting.AppUrl + pr.BaseRepo.ComposeCompareURL(pr.MergeBase, pr.MergedCommitID),
|
||||
Commits: ListToPushCommits(l).ToApiPayloadCommits(pr.BaseRepo.FullRepoLink()),
|
||||
Commits: ListToPushCommits(l).ToApiPayloadCommits(pr.BaseRepo.FullLink()),
|
||||
Repo: pr.BaseRepo.ComposePayload(),
|
||||
Pusher: &api.PayloadAuthor{
|
||||
Name: pr.HeadRepo.MustOwner().DisplayName(),
|
||||
@@ -342,9 +342,6 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str
|
||||
RepoName: repo.Name,
|
||||
IsPrivate: repo.IsPrivate,
|
||||
}
|
||||
if err = notifyWatchers(sess, act); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pr.Index = pull.Index
|
||||
if err = repo.SavePatch(pr.Index, patch); err != nil {
|
||||
@@ -364,7 +361,17 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str
|
||||
return fmt.Errorf("insert pull repo: %v", err)
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
if err = sess.Commit(); err != nil {
|
||||
return fmt.Errorf("Commit: %v", err)
|
||||
}
|
||||
|
||||
if err = NotifyWatchers(act); err != nil {
|
||||
log.Error(4, "NotifyWatchers: %v", err)
|
||||
} else if err = pull.MailParticipants(); err != nil {
|
||||
log.Error(4, "MailParticipants: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetUnmergedPullRequest returnss a pull request that is open and has not been merged
|
||||
|
||||
@@ -67,6 +67,8 @@ func createTag(gitRepo *git.Repository, rel *Release) error {
|
||||
return fmt.Errorf("GetBranchCommit: %v", err)
|
||||
}
|
||||
|
||||
// Trim '--' prefix to prevent command line argument vulnerability
|
||||
rel.TagName = strings.TrimPrefix(rel.TagName, "--")
|
||||
if err = gitRepo.CreateTag(rel.TagName, commit.ID.String()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -129,8 +129,7 @@ func NewRepoContext() {
|
||||
log.Fatal(4, "Fail to execute 'git config --global core.quotepath false': %s", stderr)
|
||||
}
|
||||
|
||||
// Clean up temporary data.
|
||||
os.RemoveAll(filepath.Join(setting.AppDataPath, "tmp"))
|
||||
RemoveAllWithNotice("Clean up repository temporary data", filepath.Join(setting.AppDataPath, "tmp"))
|
||||
}
|
||||
|
||||
// Repository represents a git repository.
|
||||
@@ -171,6 +170,7 @@ type Repository struct {
|
||||
EnableIssues bool `xorm:"NOT NULL DEFAULT true"`
|
||||
EnableExternalTracker bool
|
||||
ExternalTrackerFormat string
|
||||
ExternalTrackerStyle string
|
||||
ExternalMetas map[string]string `xorm:"-"`
|
||||
EnablePulls bool `xorm:"NOT NULL DEFAULT true"`
|
||||
|
||||
@@ -206,6 +206,10 @@ func (repo *Repository) AfterSet(colName string, _ xorm.Cell) {
|
||||
repo.NumOpenPulls = repo.NumPulls - repo.NumClosedPulls
|
||||
case "num_closed_milestones":
|
||||
repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
|
||||
case "external_tracker_style":
|
||||
if len(repo.ExternalTrackerStyle) == 0 {
|
||||
repo.ExternalTrackerStyle = markdown.ISSUE_NAME_STYLE_NUMERIC
|
||||
}
|
||||
case "created_unix":
|
||||
repo.Created = time.Unix(repo.CreatedUnix, 0).Local()
|
||||
case "updated_unix":
|
||||
@@ -255,6 +259,13 @@ func (repo *Repository) ComposeMetas() map[string]string {
|
||||
"user": repo.MustOwner().Name,
|
||||
"repo": repo.Name,
|
||||
}
|
||||
switch repo.ExternalTrackerStyle {
|
||||
case markdown.ISSUE_NAME_STYLE_ALPHANUMERIC:
|
||||
repo.ExternalMetas["style"] = markdown.ISSUE_NAME_STYLE_ALPHANUMERIC
|
||||
default:
|
||||
repo.ExternalMetas["style"] = markdown.ISSUE_NAME_STYLE_NUMERIC
|
||||
}
|
||||
|
||||
}
|
||||
return repo.ExternalMetas
|
||||
}
|
||||
@@ -335,11 +346,11 @@ func (repo *Repository) GitConfigPath() string {
|
||||
return filepath.Join(repo.RepoPath(), "config")
|
||||
}
|
||||
|
||||
func (repo *Repository) RepoLink() string {
|
||||
func (repo *Repository) Link() string {
|
||||
return setting.AppSubUrl + "/" + repo.MustOwner().Name + "/" + repo.Name
|
||||
}
|
||||
|
||||
func (repo *Repository) RepoRelLink() string {
|
||||
func (repo *Repository) RelLink() string {
|
||||
return "/" + repo.MustOwner().Name + "/" + repo.Name
|
||||
}
|
||||
|
||||
@@ -347,7 +358,7 @@ func (repo *Repository) ComposeCompareURL(oldCommitID, newCommitID string) strin
|
||||
return fmt.Sprintf("%s/%s/compare/%s...%s", repo.MustOwner().Name, repo.Name, oldCommitID, newCommitID)
|
||||
}
|
||||
|
||||
func (repo *Repository) FullRepoLink() string {
|
||||
func (repo *Repository) FullLink() string {
|
||||
return setting.AppUrl + repo.MustOwner().Name + "/" + repo.Name
|
||||
}
|
||||
|
||||
@@ -448,7 +459,7 @@ func (repo *Repository) ComposePayload() *api.PayloadRepo {
|
||||
return &api.PayloadRepo{
|
||||
ID: repo.ID,
|
||||
Name: repo.Name,
|
||||
URL: repo.FullRepoLink(),
|
||||
URL: repo.FullLink(),
|
||||
SSHURL: cl.SSH,
|
||||
CloneURL: cl.HTTPS,
|
||||
Description: repo.Description,
|
||||
@@ -507,7 +518,7 @@ func (repo *Repository) CloneLink() (cl *CloneLink) {
|
||||
}
|
||||
|
||||
var (
|
||||
reservedNames = []string{"debug", "raw", "install", "api", "avatar", "user", "org", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin", "new"}
|
||||
reservedNames = []string{"debug", "raw", "install", "api", "avatar", "user", "org", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin", "new", ".", ".."}
|
||||
reservedPatterns = []string{"*.git", "*.keys", "*.wiki"}
|
||||
)
|
||||
|
||||
@@ -536,10 +547,11 @@ func IsUsableName(name string) error {
|
||||
|
||||
// Mirror represents a mirror information of repository.
|
||||
type Mirror struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64
|
||||
Repo *Repository `xorm:"-"`
|
||||
Interval int // Hour.
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64
|
||||
Repo *Repository `xorm:"-"`
|
||||
Interval int // Hour.
|
||||
EnablePrune bool `xorm:"NOT NULL DEFAULT true"`
|
||||
|
||||
Updated time.Time `xorm:"-"`
|
||||
UpdatedUnix int64
|
||||
@@ -645,7 +657,7 @@ func GetMirror(repoId int64) (*Mirror, error) {
|
||||
}
|
||||
|
||||
func updateMirror(e Engine, m *Mirror) error {
|
||||
_, err := e.Id(m.ID).Update(m)
|
||||
_, err := e.Id(m.ID).AllCols().Update(m)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -735,9 +747,10 @@ func MigrateRepository(u *User, opts MigrateRepoOptions) (*Repository, error) {
|
||||
|
||||
if opts.IsMirror {
|
||||
if _, err = x.InsertOne(&Mirror{
|
||||
RepoID: repo.ID,
|
||||
Interval: 24,
|
||||
NextUpdate: time.Now().Add(24 * time.Hour),
|
||||
RepoID: repo.ID,
|
||||
Interval: 24,
|
||||
EnablePrune: true,
|
||||
NextUpdate: time.Now().Add(24 * time.Hour),
|
||||
}); err != nil {
|
||||
return repo, fmt.Errorf("InsertOne: %v", err)
|
||||
}
|
||||
@@ -1398,20 +1411,8 @@ func DeleteRepository(uid, repoID int64) error {
|
||||
}
|
||||
|
||||
if repo.NumForks > 0 {
|
||||
if repo.IsPrivate {
|
||||
forkRepos, err := GetRepositoriesByForkID(repo.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getRepositoriesByForkID: %v", err)
|
||||
}
|
||||
for i := range forkRepos {
|
||||
if err = DeleteRepository(forkRepos[i].OwnerID, forkRepos[i].ID); err != nil {
|
||||
log.Error(4, "DeleteRepository [%d]: %v", forkRepos[i].ID, err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if _, err = x.Exec("UPDATE `repository` SET fork_id=0,is_fork=? WHERE fork_id=?", false, repo.ID); err != nil {
|
||||
log.Error(4, "reset 'fork_id' and 'is_fork': %v", err)
|
||||
}
|
||||
if _, err = x.Exec("UPDATE `repository` SET fork_id=0,is_fork=? WHERE fork_id=?", false, repo.ID); err != nil {
|
||||
log.Error(4, "reset 'fork_id' and 'is_fork': %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1510,9 +1511,6 @@ func SearchRepositoryByName(opts *SearchRepoOptions) (repos []*Repository, _ int
|
||||
}
|
||||
opts.Keyword = strings.ToLower(opts.Keyword)
|
||||
|
||||
if opts.PageSize <= 0 || opts.PageSize > setting.ExplorePagingNum {
|
||||
opts.PageSize = setting.ExplorePagingNum
|
||||
}
|
||||
if opts.Page <= 0 {
|
||||
opts.Page = 1
|
||||
}
|
||||
@@ -1684,10 +1682,16 @@ func MirrorUpdate() {
|
||||
}
|
||||
|
||||
repoPath := m.Repo.RepoPath()
|
||||
|
||||
gitArgs := []string{"remote", "update"}
|
||||
if m.EnablePrune {
|
||||
gitArgs = append(gitArgs, "--prune")
|
||||
}
|
||||
|
||||
if _, stderr, err := process.ExecDir(
|
||||
time.Duration(setting.Git.Timeout.Mirror)*time.Second,
|
||||
repoPath, fmt.Sprintf("MirrorUpdate: %s", repoPath),
|
||||
"git", "remote", "update", "--prune"); err != nil {
|
||||
"git", gitArgs...); err != nil {
|
||||
desc := fmt.Sprintf("Fail to update mirror repository(%s): %s", repoPath, stderr)
|
||||
log.Error(4, desc)
|
||||
if err = CreateRepositoryNotice(desc); err != nil {
|
||||
@@ -1819,9 +1823,26 @@ func CheckRepoStats() {
|
||||
repoStatsCheck(checkers[i])
|
||||
}
|
||||
|
||||
// FIXME: use checker when v0.9, stop supporting old fork repo format.
|
||||
// ***** START: Repository.NumClosedIssues *****
|
||||
desc := "repository count 'num_closed_issues'"
|
||||
results, err := x.Query("SELECT repo.id FROM `repository` repo WHERE repo.num_closed_issues!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", true, false)
|
||||
if err != nil {
|
||||
log.Error(4, "Select %s: %v", desc, err)
|
||||
} else {
|
||||
for _, result := range results {
|
||||
id := com.StrTo(result["id"]).MustInt64()
|
||||
log.Trace("Updating %s: %d", desc, id)
|
||||
_, err = x.Exec("UPDATE `repository` SET num_closed_issues=(SELECT COUNT(*) FROM `issue` WHERE repo_id=? AND is_closed=? AND is_pull=?) WHERE id=?", id, true, false, id)
|
||||
if err != nil {
|
||||
log.Error(4, "Update %s[%d]: %v", desc, id, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// ***** END: Repository.NumClosedIssues *****
|
||||
|
||||
// FIXME: use checker when stop supporting old fork repo format.
|
||||
// ***** START: Repository.NumForks *****
|
||||
results, err := x.Query("SELECT repo.id FROM `repository` repo WHERE repo.num_forks!=(SELECT COUNT(*) FROM `repository` WHERE fork_id=repo.id)")
|
||||
results, err = x.Query("SELECT repo.id FROM `repository` repo WHERE repo.num_forks!=(SELECT COUNT(*) FROM `repository` WHERE fork_id=repo.id)")
|
||||
if err != nil {
|
||||
log.Error(4, "Select repository count 'num_forks': %v", err)
|
||||
} else {
|
||||
|
||||
@@ -16,16 +16,17 @@ type Collaboration struct {
|
||||
Mode AccessMode `xorm:"DEFAULT 2 NOT NULL"`
|
||||
}
|
||||
|
||||
func (c *Collaboration) ModeName() string {
|
||||
func (c *Collaboration) ModeI18nKey() string {
|
||||
switch c.Mode {
|
||||
case ACCESS_MODE_READ:
|
||||
return "Read"
|
||||
return "repo.settings.collaboration.read"
|
||||
case ACCESS_MODE_WRITE:
|
||||
return "Write"
|
||||
return "repo.settings.collaboration.write"
|
||||
case ACCESS_MODE_ADMIN:
|
||||
return "Admin"
|
||||
return "repo.settings.collaboration.admin"
|
||||
default:
|
||||
return "repo.settings.collaboration.undefined"
|
||||
}
|
||||
return "Undefined"
|
||||
}
|
||||
|
||||
// AddCollaborator adds new collaboration relation between an individual and a repository.
|
||||
|
||||
62
models/repo_test.go
Normal file
62
models/repo_test.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package models_test
|
||||
|
||||
import (
|
||||
. "github.com/gogits/gogs/models"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
"testing"
|
||||
|
||||
"github.com/gogits/gogs/modules/markdown"
|
||||
)
|
||||
|
||||
func TestRepo(t *testing.T) {
|
||||
Convey("The metas map", t, func() {
|
||||
var repo = new(Repository)
|
||||
repo.Name = "testrepo"
|
||||
repo.Owner = new(User)
|
||||
repo.Owner.Name = "testuser"
|
||||
repo.ExternalTrackerFormat = "https://someurl.com/{user}/{repo}/{issue}"
|
||||
|
||||
Convey("When no external tracker is configured", func() {
|
||||
Convey("It should be nil", func() {
|
||||
repo.EnableExternalTracker = false
|
||||
So(repo.ComposeMetas(), ShouldEqual, map[string]string(nil))
|
||||
})
|
||||
Convey("It should be nil even if other settings are present", func() {
|
||||
repo.EnableExternalTracker = false
|
||||
repo.ExternalTrackerFormat = "http://someurl.com/{user}/{repo}/{issue}"
|
||||
repo.ExternalTrackerStyle = markdown.ISSUE_NAME_STYLE_NUMERIC
|
||||
So(repo.ComposeMetas(), ShouldEqual, map[string]string(nil))
|
||||
})
|
||||
})
|
||||
|
||||
Convey("When an external issue tracker is configured", func() {
|
||||
repo.EnableExternalTracker = true
|
||||
Convey("It should default to numeric issue style", func() {
|
||||
metas := repo.ComposeMetas()
|
||||
So(metas["style"], ShouldEqual, markdown.ISSUE_NAME_STYLE_NUMERIC)
|
||||
})
|
||||
Convey("It should pass through numeric issue style setting", func() {
|
||||
repo.ExternalTrackerStyle = markdown.ISSUE_NAME_STYLE_NUMERIC
|
||||
metas := repo.ComposeMetas()
|
||||
So(metas["style"], ShouldEqual, markdown.ISSUE_NAME_STYLE_NUMERIC)
|
||||
})
|
||||
Convey("It should pass through alphanumeric issue style setting", func() {
|
||||
repo.ExternalTrackerStyle = markdown.ISSUE_NAME_STYLE_ALPHANUMERIC
|
||||
metas := repo.ComposeMetas()
|
||||
So(metas["style"], ShouldEqual, markdown.ISSUE_NAME_STYLE_ALPHANUMERIC)
|
||||
})
|
||||
Convey("It should contain the user name", func() {
|
||||
metas := repo.ComposeMetas()
|
||||
So(metas["user"], ShouldEqual, "testuser")
|
||||
})
|
||||
Convey("It should contain the repo name", func() {
|
||||
metas := repo.ComposeMetas()
|
||||
So(metas["repo"], ShouldEqual, "testrepo")
|
||||
})
|
||||
Convey("It should contain the URL format", func() {
|
||||
metas := repo.ComposeMetas()
|
||||
So(metas["format"], ShouldEqual, "https://someurl.com/{user}/{repo}/{issue}")
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -56,6 +56,9 @@ func NewAccessToken(t *AccessToken) error {
|
||||
|
||||
// GetAccessTokenBySHA returns access token by given sha1.
|
||||
func GetAccessTokenBySHA(sha string) (*AccessToken, error) {
|
||||
if sha == "" {
|
||||
return nil, ErrAccessTokenEmpty{}
|
||||
}
|
||||
t := &AccessToken{Sha1: sha}
|
||||
has, err := x.Get(t)
|
||||
if err != nil {
|
||||
|
||||
186
models/user.go
186
models/user.go
@@ -12,7 +12,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/jpeg"
|
||||
_ "image/jpeg"
|
||||
"image/png"
|
||||
"os"
|
||||
@@ -82,10 +81,11 @@ type User struct {
|
||||
MaxRepoCreation int `xorm:"NOT NULL DEFAULT -1"`
|
||||
|
||||
// Permissions
|
||||
IsActive bool
|
||||
IsActive bool // Activate primary email
|
||||
IsAdmin bool
|
||||
AllowGitHook bool
|
||||
AllowImportLocal bool // Allow migrate repository by local path
|
||||
ProhibitLogin bool
|
||||
|
||||
// Avatar
|
||||
Avatar string `xorm:"VARCHAR(2048) NOT NULL"`
|
||||
@@ -167,16 +167,6 @@ func (u *User) CanImportLocal() bool {
|
||||
return u.IsAdmin || u.AllowImportLocal
|
||||
}
|
||||
|
||||
// EmailAdresses is the list of all email addresses of a user. Can contain the
|
||||
// primary email address, but is not obligatory
|
||||
type EmailAddress struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
UID int64 `xorm:"INDEX NOT NULL"`
|
||||
Email string `xorm:"UNIQUE NOT NULL"`
|
||||
IsActivated bool
|
||||
IsPrimary bool `xorm:"-"`
|
||||
}
|
||||
|
||||
// DashboardLink returns the user dashboard page link.
|
||||
func (u *User) DashboardLink() string {
|
||||
if u.IsOrganization() {
|
||||
@@ -231,7 +221,7 @@ func (u *User) GenerateRandomAvatar() error {
|
||||
}
|
||||
defer fw.Close()
|
||||
|
||||
if err = jpeg.Encode(fw, img, nil); err != nil {
|
||||
if err = png.Encode(fw, img); err != nil {
|
||||
return fmt.Errorf("Encode: %v", err)
|
||||
}
|
||||
|
||||
@@ -240,7 +230,7 @@ func (u *User) GenerateRandomAvatar() error {
|
||||
}
|
||||
|
||||
func (u *User) RelAvatarLink() string {
|
||||
defaultImgUrl := "/img/avatar_default.jpg"
|
||||
defaultImgUrl := "/img/avatar_default.png"
|
||||
if u.Id == -1 {
|
||||
return defaultImgUrl
|
||||
}
|
||||
@@ -263,11 +253,11 @@ func (u *User) RelAvatarLink() string {
|
||||
return setting.GravatarSource + u.Avatar
|
||||
}
|
||||
|
||||
// AvatarLink returns user gravatar link.
|
||||
// AvatarLink returns user avatar link.
|
||||
func (u *User) AvatarLink() string {
|
||||
link := u.RelAvatarLink()
|
||||
if link[0] == '/' && link[1] != '/' {
|
||||
return setting.AppSubUrl + link
|
||||
return strings.TrimSuffix(setting.AppUrl, "/") + link
|
||||
}
|
||||
return link
|
||||
}
|
||||
@@ -330,7 +320,7 @@ func (u *User) UploadAvatar(data []byte) error {
|
||||
return fmt.Errorf("Decode: %v", err)
|
||||
}
|
||||
|
||||
m := resize.Resize(290, 290, img, resize.NearestNeighbor)
|
||||
m := resize.Resize(avatar.AVATAR_SIZE, avatar.AVATAR_SIZE, img, resize.NearestNeighbor)
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
@@ -464,19 +454,6 @@ func IsUserExist(uid int64, name string) (bool, error) {
|
||||
return x.Where("id!=?", uid).Get(&User{LowerName: strings.ToLower(name)})
|
||||
}
|
||||
|
||||
// IsEmailUsed returns true if the e-mail has been used.
|
||||
func IsEmailUsed(email string) (bool, error) {
|
||||
if len(email) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
email = strings.ToLower(email)
|
||||
if has, err := x.Get(&EmailAddress{Email: email}); has || err != nil {
|
||||
return has, err
|
||||
}
|
||||
return x.Get(&User{Email: email})
|
||||
}
|
||||
|
||||
// GetUserSalt returns a ramdom user salt token.
|
||||
func GetUserSalt() string {
|
||||
return base.GetRandomString(10)
|
||||
@@ -521,16 +498,14 @@ func CreateUser(u *User) (err error) {
|
||||
u.MaxRepoCreation = -1
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.Insert(u); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
} else if err = os.MkdirAll(UserPath(u.Name), os.ModePerm); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -888,8 +863,8 @@ func GetUserEmailsByNames(names []string) []string {
|
||||
return mails
|
||||
}
|
||||
|
||||
// GetUserIdsByNames returns a slice of ids corresponds to names.
|
||||
func GetUserIdsByNames(names []string) []int64 {
|
||||
// GetUserIDsByNames returns a slice of ids corresponds to names.
|
||||
func GetUserIDsByNames(names []string) []int64 {
|
||||
ids := make([]int64, 0, len(names))
|
||||
for _, name := range names {
|
||||
u, err := GetUserByName(name)
|
||||
@@ -901,147 +876,6 @@ func GetUserIdsByNames(names []string) []int64 {
|
||||
return ids
|
||||
}
|
||||
|
||||
// GetEmailAddresses returns all e-mail addresses belongs to given user.
|
||||
func GetEmailAddresses(uid int64) ([]*EmailAddress, error) {
|
||||
emails := make([]*EmailAddress, 0, 5)
|
||||
err := x.Where("uid=?", uid).Find(&emails)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
u, err := GetUserByID(uid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
isPrimaryFound := false
|
||||
for _, email := range emails {
|
||||
if email.Email == u.Email {
|
||||
isPrimaryFound = true
|
||||
email.IsPrimary = true
|
||||
} else {
|
||||
email.IsPrimary = false
|
||||
}
|
||||
}
|
||||
|
||||
// We alway want the primary email address displayed, even if it's not in
|
||||
// the emailaddress table (yet)
|
||||
if !isPrimaryFound {
|
||||
emails = append(emails, &EmailAddress{
|
||||
Email: u.Email,
|
||||
IsActivated: true,
|
||||
IsPrimary: true,
|
||||
})
|
||||
}
|
||||
return emails, nil
|
||||
}
|
||||
|
||||
func AddEmailAddress(email *EmailAddress) error {
|
||||
email.Email = strings.ToLower(strings.TrimSpace(email.Email))
|
||||
used, err := IsEmailUsed(email.Email)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if used {
|
||||
return ErrEmailAlreadyUsed{email.Email}
|
||||
}
|
||||
|
||||
_, err = x.Insert(email)
|
||||
return err
|
||||
}
|
||||
|
||||
func AddEmailAddresses(emails []*EmailAddress) error {
|
||||
if len(emails) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check if any of them has been used
|
||||
for i := range emails {
|
||||
emails[i].Email = strings.ToLower(strings.TrimSpace(emails[i].Email))
|
||||
used, err := IsEmailUsed(emails[i].Email)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if used {
|
||||
return ErrEmailAlreadyUsed{emails[i].Email}
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := x.Insert(emails); err != nil {
|
||||
return fmt.Errorf("Insert: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (email *EmailAddress) Activate() error {
|
||||
email.IsActivated = true
|
||||
if _, err := x.Id(email.ID).AllCols().Update(email); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if user, err := GetUserByID(email.UID); err != nil {
|
||||
return err
|
||||
} else {
|
||||
user.Rands = GetUserSalt()
|
||||
return UpdateUser(user)
|
||||
}
|
||||
}
|
||||
|
||||
func DeleteEmailAddress(email *EmailAddress) (err error) {
|
||||
if email.ID > 0 {
|
||||
_, err = x.Id(email.ID).Delete(new(EmailAddress))
|
||||
} else {
|
||||
_, err = x.Where("email=?", email.Email).Delete(new(EmailAddress))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func DeleteEmailAddresses(emails []*EmailAddress) (err error) {
|
||||
for i := range emails {
|
||||
if err = DeleteEmailAddress(emails[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func MakeEmailPrimary(email *EmailAddress) error {
|
||||
has, err := x.Get(email)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
return ErrEmailNotExist
|
||||
}
|
||||
|
||||
if !email.IsActivated {
|
||||
return ErrEmailNotActivated
|
||||
}
|
||||
|
||||
user := &User{Id: email.UID}
|
||||
has, err = x.Get(user)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
return ErrUserNotExist{email.UID, ""}
|
||||
}
|
||||
|
||||
// Make sure the former primary email doesn't disappear
|
||||
former_primary_email := &EmailAddress{Email: user.Email}
|
||||
has, err = x.Get(former_primary_email)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
former_primary_email.UID = user.Id
|
||||
former_primary_email.IsActivated = user.IsActive
|
||||
x.Insert(former_primary_email)
|
||||
}
|
||||
|
||||
user.Email = email.Email
|
||||
_, err = x.Id(user.Id).AllCols().Update(user)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// UserCommit represents a commit with validation of user.
|
||||
type UserCommit struct {
|
||||
User *User
|
||||
|
||||
198
models/user_mail.go
Normal file
198
models/user_mail.go
Normal file
@@ -0,0 +1,198 @@
|
||||
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// EmailAdresses is the list of all email addresses of a user. Can contain the
|
||||
// primary email address, but is not obligatory.
|
||||
type EmailAddress struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
UID int64 `xorm:"INDEX NOT NULL"`
|
||||
Email string `xorm:"UNIQUE NOT NULL"`
|
||||
IsActivated bool
|
||||
IsPrimary bool `xorm:"-"`
|
||||
}
|
||||
|
||||
// GetEmailAddresses returns all email addresses belongs to given user.
|
||||
func GetEmailAddresses(uid int64) ([]*EmailAddress, error) {
|
||||
emails := make([]*EmailAddress, 0, 5)
|
||||
if err := x.Where("uid=?", uid).Find(&emails); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
u, err := GetUserByID(uid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
isPrimaryFound := false
|
||||
for _, email := range emails {
|
||||
if email.Email == u.Email {
|
||||
isPrimaryFound = true
|
||||
email.IsPrimary = true
|
||||
} else {
|
||||
email.IsPrimary = false
|
||||
}
|
||||
}
|
||||
|
||||
// We alway want the primary email address displayed, even if it's not in
|
||||
// the emailaddress table (yet).
|
||||
if !isPrimaryFound {
|
||||
emails = append(emails, &EmailAddress{
|
||||
Email: u.Email,
|
||||
IsActivated: true,
|
||||
IsPrimary: true,
|
||||
})
|
||||
}
|
||||
return emails, nil
|
||||
}
|
||||
|
||||
func isEmailUsed(e Engine, email string) (bool, error) {
|
||||
if len(email) == 0 {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return e.Get(&EmailAddress{Email: email})
|
||||
}
|
||||
|
||||
// IsEmailUsed returns true if the email has been used.
|
||||
func IsEmailUsed(email string) (bool, error) {
|
||||
return isEmailUsed(x, email)
|
||||
}
|
||||
|
||||
func addEmailAddress(e Engine, email *EmailAddress) error {
|
||||
email.Email = strings.ToLower(strings.TrimSpace(email.Email))
|
||||
used, err := isEmailUsed(e, email.Email)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if used {
|
||||
return ErrEmailAlreadyUsed{email.Email}
|
||||
}
|
||||
|
||||
_, err = e.Insert(email)
|
||||
return err
|
||||
}
|
||||
|
||||
func AddEmailAddress(email *EmailAddress) error {
|
||||
return addEmailAddress(x, email)
|
||||
}
|
||||
|
||||
func AddEmailAddresses(emails []*EmailAddress) error {
|
||||
if len(emails) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check if any of them has been used
|
||||
for i := range emails {
|
||||
emails[i].Email = strings.ToLower(strings.TrimSpace(emails[i].Email))
|
||||
used, err := IsEmailUsed(emails[i].Email)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if used {
|
||||
return ErrEmailAlreadyUsed{emails[i].Email}
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := x.Insert(emails); err != nil {
|
||||
return fmt.Errorf("Insert: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (email *EmailAddress) Activate() error {
|
||||
user, err := GetUserByID(email.UID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user.Rands = GetUserSalt()
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
email.IsActivated = true
|
||||
if _, err := sess.Id(email.ID).AllCols().Update(email); err != nil {
|
||||
return err
|
||||
} else if err = updateUser(sess, user); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
func DeleteEmailAddress(email *EmailAddress) (err error) {
|
||||
if email.ID > 0 {
|
||||
_, err = x.Id(email.ID).Delete(new(EmailAddress))
|
||||
} else {
|
||||
_, err = x.Where("email=?", email.Email).Delete(new(EmailAddress))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func DeleteEmailAddresses(emails []*EmailAddress) (err error) {
|
||||
for i := range emails {
|
||||
if err = DeleteEmailAddress(emails[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func MakeEmailPrimary(email *EmailAddress) error {
|
||||
has, err := x.Get(email)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
return ErrEmailNotExist
|
||||
}
|
||||
|
||||
if !email.IsActivated {
|
||||
return ErrEmailNotActivated
|
||||
}
|
||||
|
||||
user := &User{Id: email.UID}
|
||||
has, err = x.Get(user)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
return ErrUserNotExist{email.UID, ""}
|
||||
}
|
||||
|
||||
// Make sure the former primary email doesn't disappear.
|
||||
formerPrimaryEmail := &EmailAddress{Email: user.Email}
|
||||
has, err = x.Get(formerPrimaryEmail)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !has {
|
||||
formerPrimaryEmail.UID = user.Id
|
||||
formerPrimaryEmail.IsActivated = user.IsActive
|
||||
if _, err = sess.Insert(formerPrimaryEmail); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
user.Email = email.Email
|
||||
if _, err = sess.Id(user.Id).AllCols().Update(user); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
@@ -174,16 +174,32 @@ func CreateWebhook(w *Webhook) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// GetWebhookByID returns webhook by given ID.
|
||||
func GetWebhookByID(id int64) (*Webhook, error) {
|
||||
w := new(Webhook)
|
||||
has, err := x.Id(id).Get(w)
|
||||
// getWebhook uses argument bean as query condition,
|
||||
// ID must be specified and do not assign unnecessary fields.
|
||||
func getWebhook(bean *Webhook) (*Webhook, error) {
|
||||
has, err := x.Get(bean)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrWebhookNotExist{id}
|
||||
return nil, ErrWebhookNotExist{bean.ID}
|
||||
}
|
||||
return w, nil
|
||||
return bean, nil
|
||||
}
|
||||
|
||||
// GetWebhookByRepoID returns webhook of repository by given ID.
|
||||
func GetWebhookByRepoID(repoID, id int64) (*Webhook, error) {
|
||||
return getWebhook(&Webhook{
|
||||
ID: id,
|
||||
RepoID: repoID,
|
||||
})
|
||||
}
|
||||
|
||||
// GetWebhookByOrgID returns webhook of organization by given ID.
|
||||
func GetWebhookByOrgID(orgID, id int64) (*Webhook, error) {
|
||||
return getWebhook(&Webhook{
|
||||
ID: id,
|
||||
OrgID: orgID,
|
||||
})
|
||||
}
|
||||
|
||||
// GetActiveWebhooksByRepoID returns all active webhooks of repository.
|
||||
@@ -204,25 +220,42 @@ func UpdateWebhook(w *Webhook) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteWebhook deletes webhook of repository.
|
||||
func DeleteWebhook(id int64) (err error) {
|
||||
// deleteWebhook uses argument bean as query condition,
|
||||
// ID must be specified and do not assign unnecessary fields.
|
||||
func deleteWebhook(bean *Webhook) (err error) {
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.Delete(&Webhook{ID: id}); err != nil {
|
||||
if _, err = sess.Delete(bean); err != nil {
|
||||
return err
|
||||
} else if _, err = sess.Delete(&HookTask{HookID: id}); err != nil {
|
||||
} else if _, err = sess.Delete(&HookTask{HookID: bean.ID}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// GetWebhooksByOrgId returns all webhooks for an organization.
|
||||
func GetWebhooksByOrgId(orgID int64) (ws []*Webhook, err error) {
|
||||
// DeleteWebhookByRepoID deletes webhook of repository by given ID.
|
||||
func DeleteWebhookByRepoID(repoID, id int64) (error) {
|
||||
return deleteWebhook(&Webhook{
|
||||
ID: id,
|
||||
RepoID: repoID,
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteWebhookByOrgID deletes webhook of organization by given ID.
|
||||
func DeleteWebhookByOrgID(orgID, id int64) (error) {
|
||||
return deleteWebhook(&Webhook{
|
||||
ID: id,
|
||||
OrgID: orgID,
|
||||
})
|
||||
}
|
||||
|
||||
// GetWebhooksByOrgID returns all webhooks for an organization.
|
||||
func GetWebhooksByOrgID(orgID int64) (ws []*Webhook, err error) {
|
||||
err = x.Find(&ws, &Webhook{OrgID: orgID})
|
||||
return ws, err
|
||||
}
|
||||
@@ -548,7 +581,7 @@ func (t *HookTask) deliver() {
|
||||
}
|
||||
|
||||
// Update webhook last delivery status.
|
||||
w, err := GetWebhookByID(t.HookID)
|
||||
w, err := GetWebhookByRepoID(t.RepoID, t.HookID)
|
||||
if err != nil {
|
||||
log.Error(5, "GetWebhookByID: %v", err)
|
||||
return
|
||||
@@ -584,14 +617,6 @@ func (t *HookTask) deliver() {
|
||||
return
|
||||
}
|
||||
t.ResponseInfo.Body = string(p)
|
||||
|
||||
switch t.Type {
|
||||
case SLACK:
|
||||
if t.ResponseInfo.Body != "ok" {
|
||||
log.Error(5, "slack failed with: %s", t.ResponseInfo.Body)
|
||||
t.IsSucceed = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeliverHooks checks and delivers undelivered hooks.
|
||||
|
||||
@@ -69,10 +69,12 @@ func ToWikiPageURL(name string) string {
|
||||
return url.QueryEscape(strings.Replace(name, " ", "-", -1))
|
||||
}
|
||||
|
||||
// ToWikiPageName formats a URL back to corresponding wiki page name.
|
||||
// ToWikiPageName formats a URL back to corresponding wiki page name,
|
||||
// and removes leading characters './' to prevent changing files
|
||||
// that are not belong to wiki repository.
|
||||
func ToWikiPageName(urlString string) string {
|
||||
name, _ := url.QueryUnescape(strings.Replace(urlString, "-", " ", -1))
|
||||
return name
|
||||
return strings.Replace(strings.TrimLeft(name, "./"), "/", " ", -1)
|
||||
}
|
||||
|
||||
// WikiCloneLink returns clone URLs of repository wiki.
|
||||
@@ -149,7 +151,7 @@ func (repo *Repository) updateWikiPage(doer *User, oldTitle, title, content, mes
|
||||
return fmt.Errorf("UpdateLocalWiki: %v", err)
|
||||
}
|
||||
|
||||
title = ToWikiPageName(strings.Replace(title, "/", " ", -1))
|
||||
title = ToWikiPageName(title)
|
||||
filename := path.Join(localPath, title+".md")
|
||||
|
||||
// If not a new file, show perform update not create.
|
||||
@@ -161,6 +163,13 @@ func (repo *Repository) updateWikiPage(doer *User, oldTitle, title, content, mes
|
||||
os.Remove(path.Join(localPath, oldTitle+".md"))
|
||||
}
|
||||
|
||||
// SECURITY: if new file is a symlink to non-exist critical file,
|
||||
// attack content can be written to the target file (e.g. authorized_keys2)
|
||||
// as a new page operation.
|
||||
// So we want to make sure the symlink is removed before write anything.
|
||||
// The new file we created will be in normal text format.
|
||||
os.Remove(filename)
|
||||
|
||||
if err = ioutil.WriteFile(filename, []byte(content), 0666); err != nil {
|
||||
return fmt.Errorf("WriteFile: %v", err)
|
||||
}
|
||||
@@ -198,7 +207,7 @@ func (repo *Repository) DeleteWikiPage(doer *User, title string) (err error) {
|
||||
return fmt.Errorf("UpdateLocalWiki: %v", err)
|
||||
}
|
||||
|
||||
title = ToWikiPageName(strings.Replace(title, "/", " ", -1))
|
||||
title = ToWikiPageName(title)
|
||||
filename := path.Join(localPath, title+".md")
|
||||
os.Remove(filename)
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ type AdminEditUserForm struct {
|
||||
Admin bool
|
||||
AllowGitHook bool
|
||||
AllowImportLocal bool
|
||||
ProhibitLogin bool
|
||||
}
|
||||
|
||||
func (f *AdminEditUserForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
|
||||
@@ -49,7 +49,7 @@ func SignedInID(ctx *macaron.Context, sess session.Store) int64 {
|
||||
if len(tokenSHA) > 0 {
|
||||
t, err := models.GetAccessTokenBySHA(tokenSHA)
|
||||
if err != nil {
|
||||
if models.IsErrAccessTokenNotExist(err) {
|
||||
if models.IsErrAccessTokenNotExist(err) || models.IsErrAccessTokenEmpty(err) {
|
||||
log.Error(4, "GetAccessTokenBySHA: %v", err)
|
||||
}
|
||||
return 0
|
||||
|
||||
@@ -31,6 +31,7 @@ type AuthenticationForm struct {
|
||||
SMTPHost string
|
||||
SMTPPort int
|
||||
AllowedDomains string
|
||||
SecurityProtocol int `binding:"Range(0,2)"`
|
||||
TLS bool
|
||||
SkipVerify bool
|
||||
PAMServiceName string
|
||||
|
||||
@@ -16,12 +16,21 @@ import (
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
)
|
||||
|
||||
type SecurityProtocol int
|
||||
|
||||
// Note: new type must be added at the end of list to maintain compatibility.
|
||||
const (
|
||||
SECURITY_PROTOCOL_UNENCRYPTED SecurityProtocol = iota
|
||||
SECURITY_PROTOCOL_LDAPS
|
||||
SECURITY_PROTOCOL_START_TLS
|
||||
)
|
||||
|
||||
// Basic LDAP authentication service
|
||||
type Source struct {
|
||||
Name string // canonical name (ie. corporate.ad)
|
||||
Host string // LDAP host
|
||||
Port int // port number
|
||||
UseSSL bool // Use SSL
|
||||
SecurityProtocol SecurityProtocol
|
||||
SkipVerify bool
|
||||
BindDN string // DN to bind with
|
||||
BindPassword string // Bind DN password
|
||||
@@ -102,9 +111,46 @@ func (ls *Source) findUserDN(l *ldap.Conn, name string) (string, bool) {
|
||||
return userDN, true
|
||||
}
|
||||
|
||||
func dial(ls *Source) (*ldap.Conn, error) {
|
||||
log.Trace("Dialing LDAP with security protocol (%v) without verifying: %v", ls.SecurityProtocol, ls.SkipVerify)
|
||||
|
||||
tlsCfg := &tls.Config{
|
||||
ServerName: ls.Host,
|
||||
InsecureSkipVerify: ls.SkipVerify,
|
||||
}
|
||||
if ls.SecurityProtocol == SECURITY_PROTOCOL_LDAPS {
|
||||
return ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port), tlsCfg)
|
||||
}
|
||||
|
||||
conn, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Dial: %v", err)
|
||||
}
|
||||
|
||||
if ls.SecurityProtocol == SECURITY_PROTOCOL_START_TLS {
|
||||
if err = conn.StartTLS(tlsCfg); err != nil {
|
||||
conn.Close()
|
||||
return nil, fmt.Errorf("StartTLS: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func bindUser(l *ldap.Conn, userDN, passwd string) error {
|
||||
log.Trace("Binding with userDN: %s", userDN)
|
||||
err := l.Bind(userDN, passwd)
|
||||
if err != nil {
|
||||
log.Debug("LDAP auth. failed for %s, reason: %v", userDN, err)
|
||||
return err
|
||||
}
|
||||
log.Trace("Bound successfully with userDN: %s", userDN)
|
||||
return err
|
||||
}
|
||||
|
||||
// searchEntry : search an LDAP source if an entry (name, passwd) is valid and in the specific filter
|
||||
func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, string, string, string, bool, bool) {
|
||||
l, err := ldapDial(ls)
|
||||
l, err := dial(ls)
|
||||
if err != nil {
|
||||
log.Error(4, "LDAP Connect error, %s:%v", ls.Host, err)
|
||||
ls.Enabled = false
|
||||
@@ -164,12 +210,12 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
|
||||
return "", "", "", "", false, false
|
||||
}
|
||||
|
||||
username_attr := sr.Entries[0].GetAttributeValue(ls.AttributeUsername)
|
||||
name_attr := sr.Entries[0].GetAttributeValue(ls.AttributeName)
|
||||
sn_attr := sr.Entries[0].GetAttributeValue(ls.AttributeSurname)
|
||||
mail_attr := sr.Entries[0].GetAttributeValue(ls.AttributeMail)
|
||||
username := sr.Entries[0].GetAttributeValue(ls.AttributeUsername)
|
||||
firstname := sr.Entries[0].GetAttributeValue(ls.AttributeName)
|
||||
surname := sr.Entries[0].GetAttributeValue(ls.AttributeSurname)
|
||||
mail := sr.Entries[0].GetAttributeValue(ls.AttributeMail)
|
||||
|
||||
admin_attr := false
|
||||
isAdmin := false
|
||||
if len(ls.AdminFilter) > 0 {
|
||||
log.Trace("Checking admin with filter %s and base %s", ls.AdminFilter, userDN)
|
||||
search = ldap.NewSearchRequest(
|
||||
@@ -183,7 +229,7 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
|
||||
} else if len(sr.Entries) < 1 {
|
||||
log.Error(4, "LDAP Admin Search failed")
|
||||
} else {
|
||||
admin_attr = true
|
||||
isAdmin = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,27 +241,5 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
|
||||
}
|
||||
}
|
||||
|
||||
return username_attr, name_attr, sn_attr, mail_attr, admin_attr, true
|
||||
}
|
||||
|
||||
func bindUser(l *ldap.Conn, userDN, passwd string) error {
|
||||
log.Trace("Binding with userDN: %s", userDN)
|
||||
err := l.Bind(userDN, passwd)
|
||||
if err != nil {
|
||||
log.Debug("LDAP auth. failed for %s, reason: %v", userDN, err)
|
||||
return err
|
||||
}
|
||||
log.Trace("Bound successfully with userDN: %s", userDN)
|
||||
return err
|
||||
}
|
||||
|
||||
func ldapDial(ls *Source) (*ldap.Conn, error) {
|
||||
if ls.UseSSL {
|
||||
log.Debug("Using TLS for LDAP without verifying: %v", ls.SkipVerify)
|
||||
return ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port), &tls.Config{
|
||||
InsecureSkipVerify: ls.SkipVerify,
|
||||
})
|
||||
} else {
|
||||
return ldap.Dial("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port))
|
||||
}
|
||||
return username, firstname, surname, mail, isAdmin, true
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ type RepoSettingForm struct {
|
||||
Interval int
|
||||
MirrorAddress string
|
||||
Private bool
|
||||
EnablePrune bool
|
||||
|
||||
// Advanced settings
|
||||
EnableWiki bool
|
||||
@@ -96,6 +97,7 @@ type RepoSettingForm struct {
|
||||
EnableIssues bool
|
||||
EnableExternalTracker bool
|
||||
TrackerURLFormat string
|
||||
TrackerIssueStyle string
|
||||
EnablePulls bool
|
||||
}
|
||||
|
||||
@@ -141,7 +143,7 @@ func (f *NewWebhookForm) Validate(ctx *macaron.Context, errs binding.Errors) bin
|
||||
}
|
||||
|
||||
type NewSlackHookForm struct {
|
||||
PayloadURL string `binding:"Required;Url`
|
||||
PayloadURL string `binding:"Required;Url"`
|
||||
Channel string `binding:"Required"`
|
||||
Username string
|
||||
IconURL string
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/issue9/identicon"
|
||||
)
|
||||
|
||||
const _RANDOM_AVATAR_SIZE = 200
|
||||
const AVATAR_SIZE = 290
|
||||
|
||||
// RandomImage generates and returns a random avatar image unique to input data
|
||||
// in custom size (height and width).
|
||||
@@ -39,5 +39,5 @@ func RandomImageSize(size int, data []byte) (image.Image, error) {
|
||||
// RandomImage generates and returns a random avatar image unique to input data
|
||||
// in default size (height and width).
|
||||
func RandomImage(data []byte) (image.Image, error) {
|
||||
return RandomImageSize(_RANDOM_AVATAR_SIZE, data)
|
||||
return RandomImageSize(AVATAR_SIZE, data)
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ func HashEmail(email string) string {
|
||||
// AvatarLink returns avatar link by given email.
|
||||
func AvatarLink(email string) string {
|
||||
if setting.DisableGravatar || setting.OfflineMode {
|
||||
return setting.AppSubUrl + "/img/avatar_default.jpg"
|
||||
return setting.AppSubUrl + "/img/avatar_default.png"
|
||||
}
|
||||
|
||||
return setting.GravatarSource + HashEmail(email)
|
||||
@@ -522,3 +522,11 @@ func IsImageFile(data []byte) (string, bool) {
|
||||
}
|
||||
return contentType, false
|
||||
}
|
||||
|
||||
func IsPDFFile(data []byte) (string, bool) {
|
||||
contentType := http.DetectContentType(data)
|
||||
if strings.Index(contentType, "application/pdf") != -1 {
|
||||
return contentType, true
|
||||
}
|
||||
return contentType, false
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -18,6 +18,7 @@ import (
|
||||
|
||||
type APIContext struct {
|
||||
*Context
|
||||
Org *APIOrganization
|
||||
}
|
||||
|
||||
// Error responses error message to client with given message.
|
||||
@@ -40,6 +41,7 @@ func (ctx *APIContext) Error(status int, title string, obj interface{}) {
|
||||
})
|
||||
}
|
||||
|
||||
// SetLinkHeader sets pagination link header by given totol number and page size.
|
||||
func (ctx *APIContext) SetLinkHeader(total, pageSize int) {
|
||||
page := paginater.New(total, pageSize, ctx.QueryInt("page"), 0)
|
||||
links := make([]string, 0, 4)
|
||||
|
||||
14
modules/context/api_org.go
Normal file
14
modules/context/api_org.go
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
"github.com/gogits/gogs/models"
|
||||
)
|
||||
|
||||
type APIOrganization struct {
|
||||
Organization *models.User
|
||||
Team *models.Team
|
||||
}
|
||||
@@ -29,7 +29,14 @@ func Toggle(options *ToggleOptions) macaron.Handler {
|
||||
return
|
||||
}
|
||||
|
||||
// Checking non-logged users landing page.
|
||||
// Check prohibit login users.
|
||||
if ctx.IsSigned && ctx.User.ProhibitLogin {
|
||||
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
|
||||
ctx.HTML(200, "user/auth/prohibit_login")
|
||||
return
|
||||
}
|
||||
|
||||
// Check non-logged users landing page.
|
||||
if !ctx.IsSigned && ctx.Req.RequestURI == "/" && setting.LandingPageUrl != setting.LANDING_PAGE_HOME {
|
||||
ctx.Redirect(setting.AppSubUrl + string(setting.LandingPageUrl))
|
||||
return
|
||||
|
||||
@@ -160,6 +160,7 @@ func RepoAssignment(args ...bool) macaron.Handler {
|
||||
ctx.Handle(500, "GetMirror", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["MirrorEnablePrune"] = ctx.Repo.Mirror.EnablePrune
|
||||
ctx.Data["MirrorInterval"] = ctx.Repo.Mirror.Interval
|
||||
ctx.Data["Mirror"] = ctx.Repo.Mirror
|
||||
}
|
||||
@@ -173,7 +174,7 @@ func RepoAssignment(args ...bool) macaron.Handler {
|
||||
return
|
||||
}
|
||||
ctx.Repo.GitRepo = gitRepo
|
||||
ctx.Repo.RepoLink = repo.RepoLink()
|
||||
ctx.Repo.RepoLink = repo.Link()
|
||||
ctx.Data["RepoLink"] = ctx.Repo.RepoLink
|
||||
ctx.Data["RepoRelPath"] = ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name
|
||||
|
||||
|
||||
@@ -23,10 +23,10 @@ func NewLogger(bufLen int64, mode, config string) {
|
||||
logger := newLogger(bufLen)
|
||||
|
||||
isExist := false
|
||||
for _, l := range loggers {
|
||||
for i, l := range loggers {
|
||||
if l.adapter == mode {
|
||||
isExist = true
|
||||
l = logger
|
||||
loggers[i] = logger
|
||||
}
|
||||
}
|
||||
if !isExist {
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package mailer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/gomail.v2"
|
||||
"gopkg.in/macaron.v1"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/markdown"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
AUTH_ACTIVATE base.TplName = "mail/auth/activate"
|
||||
AUTH_ACTIVATE_EMAIL base.TplName = "mail/auth/activate_email"
|
||||
AUTH_REGISTER_NOTIFY base.TplName = "mail/auth/register_notify"
|
||||
AUTH_RESET_PASSWORD base.TplName = "mail/auth/reset_passwd"
|
||||
|
||||
NOTIFY_COLLABORATOR base.TplName = "mail/notify/collaborator"
|
||||
NOTIFY_MENTION base.TplName = "mail/notify/mention"
|
||||
)
|
||||
|
||||
func ComposeTplData(u *models.User) map[interface{}]interface{} {
|
||||
data := make(map[interface{}]interface{}, 10)
|
||||
data["AppName"] = setting.AppName
|
||||
data["AppVer"] = setting.AppVer
|
||||
data["AppUrl"] = setting.AppUrl
|
||||
data["ActiveCodeLives"] = setting.Service.ActiveCodeLives / 60
|
||||
data["ResetPwdCodeLives"] = setting.Service.ResetPwdCodeLives / 60
|
||||
|
||||
if u != nil {
|
||||
data["User"] = u
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func SendUserMail(c *macaron.Context, u *models.User, tpl base.TplName, code, subject, info string) {
|
||||
data := ComposeTplData(u)
|
||||
data["Code"] = code
|
||||
body, err := c.HTMLString(string(tpl), data)
|
||||
if err != nil {
|
||||
log.Error(4, "HTMLString: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
msg := NewMessage([]string{u.Email}, subject, body)
|
||||
msg.Info = fmt.Sprintf("UID: %d, %s", u.Id, info)
|
||||
|
||||
SendAsync(msg)
|
||||
}
|
||||
|
||||
func SendActivateAccountMail(c *macaron.Context, u *models.User) {
|
||||
SendUserMail(c, u, AUTH_ACTIVATE, u.GenerateActivateCode(), c.Tr("mail.activate_account"), "activate account")
|
||||
}
|
||||
|
||||
// SendResetPasswordMail sends reset password e-mail.
|
||||
func SendResetPasswordMail(c *macaron.Context, u *models.User) {
|
||||
SendUserMail(c, u, AUTH_RESET_PASSWORD, u.GenerateActivateCode(), c.Tr("mail.reset_password"), "reset password")
|
||||
}
|
||||
|
||||
// SendRegisterNotifyMail triggers a notify e-mail by admin created a account.
|
||||
func SendRegisterNotifyMail(c *macaron.Context, u *models.User) {
|
||||
body, err := c.HTMLString(string(AUTH_REGISTER_NOTIFY), ComposeTplData(u))
|
||||
if err != nil {
|
||||
log.Error(4, "HTMLString: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
msg := NewMessage([]string{u.Email}, c.Tr("mail.register_notify"), body)
|
||||
msg.Info = fmt.Sprintf("UID: %d, registration notify", u.Id)
|
||||
|
||||
SendAsync(msg)
|
||||
}
|
||||
|
||||
// SendActivateAccountMail sends confirmation e-mail.
|
||||
func SendActivateEmailMail(c *macaron.Context, u *models.User, email *models.EmailAddress) {
|
||||
data := ComposeTplData(u)
|
||||
data["Code"] = u.GenerateEmailActivateCode(email.Email)
|
||||
data["Email"] = email.Email
|
||||
body, err := c.HTMLString(string(AUTH_ACTIVATE_EMAIL), data)
|
||||
if err != nil {
|
||||
log.Error(4, "HTMLString: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
msg := NewMessage([]string{email.Email}, c.Tr("mail.activate_email"), body)
|
||||
msg.Info = fmt.Sprintf("UID: %d, activate email", u.Id)
|
||||
|
||||
SendAsync(msg)
|
||||
}
|
||||
|
||||
// SendIssueNotifyMail sends mail notification of all watchers of repository.
|
||||
func SendIssueNotifyMail(u, owner *models.User, repo *models.Repository, issue *models.Issue) ([]string, error) {
|
||||
ws, err := models.GetWatchers(repo.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetWatchers[%d]: %v", repo.ID, err)
|
||||
}
|
||||
|
||||
tos := make([]string, 0, len(ws))
|
||||
for i := range ws {
|
||||
uid := ws[i].UserID
|
||||
if u.Id == uid {
|
||||
continue
|
||||
}
|
||||
to, err := models.GetUserByID(uid)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetUserByID: %v", err)
|
||||
}
|
||||
if to.IsOrganization() {
|
||||
continue
|
||||
}
|
||||
|
||||
tos = append(tos, to.Email)
|
||||
}
|
||||
|
||||
if len(tos) == 0 {
|
||||
return tos, nil
|
||||
}
|
||||
|
||||
subject := fmt.Sprintf("[%s] %s (#%d)", repo.Name, issue.Name, issue.Index)
|
||||
content := fmt.Sprintf("%s<br>-<br> <a href=\"%s%s/%s/issues/%d\">View it on Gogs</a>.",
|
||||
markdown.RenderSpecialLink([]byte(strings.Replace(issue.Content, "\n", "<br>", -1)), owner.Name+"/"+repo.Name, repo.ComposeMetas()),
|
||||
setting.AppUrl, owner.Name, repo.Name, issue.Index)
|
||||
msg := NewMessage(tos, subject, content)
|
||||
msg.Info = fmt.Sprintf("Subject: %s, issue notify", subject)
|
||||
|
||||
SendAsync(msg)
|
||||
return tos, nil
|
||||
}
|
||||
|
||||
// SendIssueMentionMail sends mail notification for who are mentioned in issue.
|
||||
func SendIssueMentionMail(r macaron.Render, u, owner *models.User,
|
||||
repo *models.Repository, issue *models.Issue, tos []string) error {
|
||||
|
||||
if len(tos) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
subject := fmt.Sprintf("[%s] %s (#%d)", repo.Name, issue.Name, issue.Index)
|
||||
|
||||
data := ComposeTplData(nil)
|
||||
data["IssueLink"] = fmt.Sprintf("%s/%s/issues/%d", owner.Name, repo.Name, issue.Index)
|
||||
data["Subject"] = subject
|
||||
data["ActUserName"] = u.DisplayName()
|
||||
data["Content"] = string(markdown.RenderSpecialLink([]byte(issue.Content), owner.Name+"/"+repo.Name, repo.ComposeMetas()))
|
||||
|
||||
body, err := r.HTMLString(string(NOTIFY_MENTION), data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("HTMLString: %v", err)
|
||||
}
|
||||
|
||||
msg := NewMessage(tos, subject, body)
|
||||
msg.Info = fmt.Sprintf("Subject: %s, issue mention", subject)
|
||||
|
||||
SendAsync(msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SendCollaboratorMail sends mail notification to new collaborator.
|
||||
func SendCollaboratorMail(r macaron.Render, u, doer *models.User, repo *models.Repository) error {
|
||||
subject := fmt.Sprintf("%s added you to %s/%s", doer.Name, repo.Owner.Name, repo.Name)
|
||||
|
||||
data := ComposeTplData(nil)
|
||||
data["RepoLink"] = path.Join(repo.Owner.Name, repo.Name)
|
||||
data["Subject"] = subject
|
||||
|
||||
body, err := r.HTMLString(string(NOTIFY_COLLABORATOR), data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("HTMLString: %v", err)
|
||||
}
|
||||
|
||||
msg := NewMessage([]string{u.Email}, subject, body)
|
||||
msg.Info = fmt.Sprintf("UID: %d, add collaborator", u.Id)
|
||||
|
||||
SendAsync(msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
func SendTestMail(email string) error {
|
||||
return gomail.Send(&Sender{}, NewMessage([]string{email}, "Gogs Test Email!", "Gogs Test Email!").Message)
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jaytaylor/html2text"
|
||||
"gopkg.in/gomail.v2"
|
||||
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
@@ -26,14 +27,25 @@ type Message struct {
|
||||
}
|
||||
|
||||
// NewMessageFrom creates new mail message object with custom From header.
|
||||
func NewMessageFrom(to []string, from, subject, body string) *Message {
|
||||
func NewMessageFrom(to []string, from, subject, htmlBody string) *Message {
|
||||
log.Trace("NewMessageFrom (htmlBody):\n%s", htmlBody)
|
||||
|
||||
msg := gomail.NewMessage()
|
||||
msg.SetHeader("From", from)
|
||||
msg.SetHeader("To", to...)
|
||||
msg.SetHeader("Subject", subject)
|
||||
msg.SetDateHeader("Date", time.Now())
|
||||
msg.SetBody("text/plain", body)
|
||||
msg.AddAlternative("text/html", body)
|
||||
|
||||
body, err := html2text.FromString(htmlBody)
|
||||
if err != nil {
|
||||
log.Error(4, "html2text.FromString: %v", err)
|
||||
msg.SetBody("text/html", htmlBody)
|
||||
} else {
|
||||
msg.SetBody("text/plain", body)
|
||||
if setting.MailService.EnableHTMLAlternative {
|
||||
msg.AddAlternative("text/html", htmlBody)
|
||||
}
|
||||
}
|
||||
|
||||
return &Message{
|
||||
Message: msg,
|
||||
@@ -186,7 +198,7 @@ func processMailQueue() {
|
||||
case msg := <-mailQueue:
|
||||
log.Trace("New e-mail sending request %s: %s", msg.GetHeader("To"), msg.Info)
|
||||
if err := gomail.Send(sender, msg.Message); err != nil {
|
||||
log.Error(4, "Fail to send e-mails %s: %s - %v", msg.GetHeader("To"), msg.Info, err)
|
||||
log.Error(3, "Fail to send emails %s: %s - %v", msg.GetHeader("To"), msg.Info, err)
|
||||
} else {
|
||||
log.Trace("E-mails sent %s: %s", msg.GetHeader("To"), msg.Info)
|
||||
}
|
||||
|
||||
@@ -22,6 +22,11 @@ import (
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
ISSUE_NAME_STYLE_NUMERIC = "numeric"
|
||||
ISSUE_NAME_STYLE_ALPHANUMERIC = "alphanumeric"
|
||||
)
|
||||
|
||||
var Sanitizer = bluemonday.UGCPolicy()
|
||||
|
||||
// BuildSanitizer initializes sanitizer with allowed attributes based on settings.
|
||||
@@ -79,13 +84,25 @@ var (
|
||||
// IssueFullPattern matches link to an issue with or without trailing hash,
|
||||
// e.g. https://try.gogs.io/gogs/gogs/issues/4#issue-685
|
||||
IssueFullPattern = regexp.MustCompile(`(\s|^)https?.*issues/[0-9]+(#+[0-9a-zA-Z-]*)?`)
|
||||
// IssueIndexPattern matches string that references to an issue, e.g. #1287
|
||||
IssueIndexPattern = regexp.MustCompile(`( |^|\()#[0-9]+\b`)
|
||||
// IssueNumericPattern matches string that references to a numeric issue, e.g. #1287
|
||||
IssueNumericPattern = regexp.MustCompile(`( |^|\()#[0-9]+\b`)
|
||||
// IssueAlphanumericPattern matches string that references to an alphanumeric issue, e.g. ABC-1234
|
||||
IssueAlphanumericPattern = regexp.MustCompile(`( |^|\()[A-Z]{1,10}-[1-9][0-9]*\b`)
|
||||
|
||||
// Sha1CurrentPattern matches string that represents a commit SHA, e.g. d8a994ef243349f321568f9e36d5c3f444b99cae
|
||||
Sha1CurrentPattern = regexp.MustCompile(`\b[0-9a-f]{40}\b`)
|
||||
)
|
||||
|
||||
// FindAllMentions matches mention patterns in given content
|
||||
// and returns a list of found user names without @ prefix.
|
||||
func FindAllMentions(content string) []string {
|
||||
mentions := MentionPattern.FindAllString(content, -1)
|
||||
for i := range mentions {
|
||||
mentions[i] = strings.TrimSpace(mentions[i])[1:] // Strip @ character
|
||||
}
|
||||
return mentions
|
||||
}
|
||||
|
||||
// Renderer is a extended version of underlying render object.
|
||||
type Renderer struct {
|
||||
blackfriday.Renderer
|
||||
@@ -113,28 +130,30 @@ func (r *Renderer) AutoLink(out *bytes.Buffer, link []byte, kind int) {
|
||||
|
||||
// Since this method could only possibly serve one link at a time,
|
||||
// we do not need to find all.
|
||||
m := CommitPattern.Find(link)
|
||||
if m != nil {
|
||||
m = bytes.TrimSpace(m)
|
||||
i := strings.Index(string(m), "commit/")
|
||||
j := strings.Index(string(m), "#")
|
||||
if j == -1 {
|
||||
j = len(m)
|
||||
if bytes.HasPrefix(link, []byte(setting.AppUrl)) {
|
||||
m := CommitPattern.Find(link)
|
||||
if m != nil {
|
||||
m = bytes.TrimSpace(m)
|
||||
i := strings.Index(string(m), "commit/")
|
||||
j := strings.Index(string(m), "#")
|
||||
if j == -1 {
|
||||
j = len(m)
|
||||
}
|
||||
out.WriteString(fmt.Sprintf(` <code><a href="%s">%s</a></code>`, m, base.ShortSha(string(m[i+7:j]))))
|
||||
return
|
||||
}
|
||||
out.WriteString(fmt.Sprintf(` <code><a href="%s">%s</a></code>`, m, base.ShortSha(string(m[i+7:j]))))
|
||||
return
|
||||
}
|
||||
|
||||
m = IssueFullPattern.Find(link)
|
||||
if m != nil {
|
||||
m = bytes.TrimSpace(m)
|
||||
i := strings.Index(string(m), "issues/")
|
||||
j := strings.Index(string(m), "#")
|
||||
if j == -1 {
|
||||
j = len(m)
|
||||
m = IssueFullPattern.Find(link)
|
||||
if m != nil {
|
||||
m = bytes.TrimSpace(m)
|
||||
i := strings.Index(string(m), "issues/")
|
||||
j := strings.Index(string(m), "#")
|
||||
if j == -1 {
|
||||
j = len(m)
|
||||
}
|
||||
out.WriteString(fmt.Sprintf(`<a href="%s">#%s</a>`, m, base.ShortSha(string(m[i+7:j]))))
|
||||
return
|
||||
}
|
||||
out.WriteString(fmt.Sprintf(` <a href="%s">#%s</a>`, m, base.ShortSha(string(m[i+7:j]))))
|
||||
return
|
||||
}
|
||||
|
||||
r.Renderer.AutoLink(out, link, kind)
|
||||
@@ -193,6 +212,9 @@ func (r *Renderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byt
|
||||
// cutoutVerbosePrefix cutouts URL prefix including sub-path to
|
||||
// return a clean unified string of request URL path.
|
||||
func cutoutVerbosePrefix(prefix string) string {
|
||||
if len(prefix) == 0 || prefix[0] != '/' {
|
||||
return prefix
|
||||
}
|
||||
count := 0
|
||||
for i := 0; i < len(prefix); i++ {
|
||||
if prefix[i] == '/' {
|
||||
@@ -208,22 +230,30 @@ func cutoutVerbosePrefix(prefix string) string {
|
||||
// RenderIssueIndexPattern renders issue indexes to corresponding links.
|
||||
func RenderIssueIndexPattern(rawBytes []byte, urlPrefix string, metas map[string]string) []byte {
|
||||
urlPrefix = cutoutVerbosePrefix(urlPrefix)
|
||||
ms := IssueIndexPattern.FindAll(rawBytes, -1)
|
||||
|
||||
pattern := IssueNumericPattern
|
||||
if metas["style"] == ISSUE_NAME_STYLE_ALPHANUMERIC {
|
||||
pattern = IssueAlphanumericPattern
|
||||
}
|
||||
|
||||
ms := pattern.FindAll(rawBytes, -1)
|
||||
for _, m := range ms {
|
||||
var space string
|
||||
if m[0] != '#' {
|
||||
space = string(m[0])
|
||||
m = m[1:]
|
||||
if m[0] == ' ' || m[0] == '(' {
|
||||
m = m[1:] // ignore leading space or opening parentheses
|
||||
}
|
||||
var link string
|
||||
if metas == nil {
|
||||
rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(`%s<a href="%s/issues/%s">%s</a>`,
|
||||
space, urlPrefix, m[1:], m)), 1)
|
||||
link = fmt.Sprintf(`<a href="%s/issues/%s">%s</a>`, urlPrefix, m[1:], m)
|
||||
} else {
|
||||
// Support for external issue tracker
|
||||
metas["index"] = string(m[1:])
|
||||
rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(`%s<a href="%s">%s</a>`,
|
||||
space, com.Expand(metas["format"], metas), m)), 1)
|
||||
if metas["style"] == ISSUE_NAME_STYLE_ALPHANUMERIC {
|
||||
metas["index"] = string(m)
|
||||
} else {
|
||||
metas["index"] = string(m[1:])
|
||||
}
|
||||
link = fmt.Sprintf(`<a href="%s">%s</a>`, com.Expand(metas["format"], metas), m)
|
||||
}
|
||||
rawBytes = bytes.Replace(rawBytes, m, []byte(link), 1)
|
||||
}
|
||||
return rawBytes
|
||||
}
|
||||
|
||||
308
modules/markdown/markdown_test.go
Normal file
308
modules/markdown/markdown_test.go
Normal file
@@ -0,0 +1,308 @@
|
||||
package markdown_test
|
||||
|
||||
import (
|
||||
. "github.com/gogits/gogs/modules/markdown"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
"testing"
|
||||
|
||||
"bytes"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
"github.com/russross/blackfriday"
|
||||
)
|
||||
|
||||
func TestMarkdown(t *testing.T) {
|
||||
Convey("Rendering an issue mention", t, func() {
|
||||
var (
|
||||
urlPrefix = "/prefix"
|
||||
metas map[string]string = nil
|
||||
)
|
||||
setting.AppSubUrlDepth = 0
|
||||
|
||||
Convey("To the internal issue tracker", func() {
|
||||
Convey("It should not render anything when there are no mentions", func() {
|
||||
testCases := []string{
|
||||
"",
|
||||
"this is a test",
|
||||
"test 123 123 1234",
|
||||
"#",
|
||||
"# # #",
|
||||
"# 123",
|
||||
"#abcd",
|
||||
"##1234",
|
||||
"test#1234",
|
||||
"#1234test",
|
||||
" test #1234test",
|
||||
}
|
||||
|
||||
for i := 0; i < len(testCases); i++ {
|
||||
So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i])
|
||||
}
|
||||
})
|
||||
Convey("It should render freestanding mentions", func() {
|
||||
testCases := []string{
|
||||
"#1234 test", "<a href=\"/prefix/issues/1234\">#1234</a> test",
|
||||
"test #1234 issue", "test <a href=\"/prefix/issues/1234\">#1234</a> issue",
|
||||
"test issue #1234", "test issue <a href=\"/prefix/issues/1234\">#1234</a>",
|
||||
"#5 test", "<a href=\"/prefix/issues/5\">#5</a> test",
|
||||
"test #5 issue", "test <a href=\"/prefix/issues/5\">#5</a> issue",
|
||||
"test issue #5", "test issue <a href=\"/prefix/issues/5\">#5</a>",
|
||||
}
|
||||
|
||||
for i := 0; i < len(testCases); i += 2 {
|
||||
So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
|
||||
}
|
||||
})
|
||||
Convey("It should not render issue mention without leading space", func() {
|
||||
input := []byte("test#54321 issue")
|
||||
expected := "test#54321 issue"
|
||||
So(string(RenderIssueIndexPattern(input, urlPrefix, metas)), ShouldEqual, expected)
|
||||
})
|
||||
Convey("It should not render issue mention without trailing space", func() {
|
||||
input := []byte("test #54321issue")
|
||||
expected := "test #54321issue"
|
||||
So(string(RenderIssueIndexPattern(input, urlPrefix, metas)), ShouldEqual, expected)
|
||||
})
|
||||
Convey("It should render issue mention in parentheses", func() {
|
||||
testCases := []string{
|
||||
"(#54321 issue)", "(<a href=\"/prefix/issues/54321\">#54321</a> issue)",
|
||||
"test (#54321) issue", "test (<a href=\"/prefix/issues/54321\">#54321</a>) issue",
|
||||
"test (#54321 extra) issue", "test (<a href=\"/prefix/issues/54321\">#54321</a> extra) issue",
|
||||
"test (#54321 issue)", "test (<a href=\"/prefix/issues/54321\">#54321</a> issue)",
|
||||
"test (#54321)", "test (<a href=\"/prefix/issues/54321\">#54321</a>)",
|
||||
}
|
||||
|
||||
for i := 0; i < len(testCases); i += 2 {
|
||||
So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
|
||||
}
|
||||
})
|
||||
Convey("It should render multiple issue mentions in the same line", func() {
|
||||
testCases := []string{
|
||||
"#54321 #1243", "<a href=\"/prefix/issues/54321\">#54321</a> <a href=\"/prefix/issues/1243\">#1243</a>",
|
||||
"test #54321 #1243", "test <a href=\"/prefix/issues/54321\">#54321</a> <a href=\"/prefix/issues/1243\">#1243</a>",
|
||||
"(#54321 #1243)", "(<a href=\"/prefix/issues/54321\">#54321</a> <a href=\"/prefix/issues/1243\">#1243</a>)",
|
||||
"(#54321)(#1243)", "(<a href=\"/prefix/issues/54321\">#54321</a>)(<a href=\"/prefix/issues/1243\">#1243</a>)",
|
||||
"text #54321 test #1243 issue", "text <a href=\"/prefix/issues/54321\">#54321</a> test <a href=\"/prefix/issues/1243\">#1243</a> issue",
|
||||
"#1 (#4321) test", "<a href=\"/prefix/issues/1\">#1</a> (<a href=\"/prefix/issues/4321\">#4321</a>) test",
|
||||
}
|
||||
|
||||
for i := 0; i < len(testCases); i += 2 {
|
||||
So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
|
||||
}
|
||||
})
|
||||
})
|
||||
Convey("To an external issue tracker with numeric style", func() {
|
||||
metas = make(map[string]string)
|
||||
metas["format"] = "https://someurl.com/{user}/{repo}/{index}"
|
||||
metas["user"] = "someuser"
|
||||
metas["repo"] = "somerepo"
|
||||
metas["style"] = ISSUE_NAME_STYLE_NUMERIC
|
||||
|
||||
Convey("should not render anything when there are no mentions", func() {
|
||||
testCases := []string{
|
||||
"this is a test",
|
||||
"test 123 123 1234",
|
||||
"#",
|
||||
"# # #",
|
||||
"# 123",
|
||||
"#abcd",
|
||||
}
|
||||
|
||||
for i := 0; i < len(testCases); i++ {
|
||||
So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i])
|
||||
}
|
||||
})
|
||||
Convey("It should render freestanding issue mentions", func() {
|
||||
testCases := []string{
|
||||
"#1234 test", "<a href=\"https://someurl.com/someuser/somerepo/1234\">#1234</a> test",
|
||||
"test #1234 issue", "test <a href=\"https://someurl.com/someuser/somerepo/1234\">#1234</a> issue",
|
||||
"test issue #1234", "test issue <a href=\"https://someurl.com/someuser/somerepo/1234\">#1234</a>",
|
||||
"#5 test", "<a href=\"https://someurl.com/someuser/somerepo/5\">#5</a> test",
|
||||
"test #5 issue", "test <a href=\"https://someurl.com/someuser/somerepo/5\">#5</a> issue",
|
||||
"test issue #5", "test issue <a href=\"https://someurl.com/someuser/somerepo/5\">#5</a>",
|
||||
}
|
||||
for i := 0; i < len(testCases); i += 2 {
|
||||
So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
|
||||
}
|
||||
})
|
||||
Convey("It should not render issue mention without leading space", func() {
|
||||
input := []byte("test#54321 issue")
|
||||
expected := "test#54321 issue"
|
||||
So(string(RenderIssueIndexPattern(input, urlPrefix, metas)), ShouldEqual, expected)
|
||||
})
|
||||
Convey("It should not render issue mention without trailing space", func() {
|
||||
input := []byte("test #54321issue")
|
||||
expected := "test #54321issue"
|
||||
So(string(RenderIssueIndexPattern(input, urlPrefix, metas)), ShouldEqual, expected)
|
||||
})
|
||||
Convey("It should render issue mention in parentheses", func() {
|
||||
testCases := []string{
|
||||
"(#54321 issue)", "(<a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a> issue)",
|
||||
"test (#54321) issue", "test (<a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a>) issue",
|
||||
"test (#54321 extra) issue", "test (<a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a> extra) issue",
|
||||
"test (#54321 issue)", "test (<a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a> issue)",
|
||||
"test (#54321)", "test (<a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a>)",
|
||||
}
|
||||
|
||||
for i := 0; i < len(testCases); i += 2 {
|
||||
So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
|
||||
}
|
||||
})
|
||||
Convey("It should render multiple issue mentions in the same line", func() {
|
||||
testCases := []string{
|
||||
"#54321 #1243", "<a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a> <a href=\"https://someurl.com/someuser/somerepo/1243\">#1243</a>",
|
||||
"test #54321 #1243", "test <a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a> <a href=\"https://someurl.com/someuser/somerepo/1243\">#1243</a>",
|
||||
"(#54321 #1243)", "(<a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a> <a href=\"https://someurl.com/someuser/somerepo/1243\">#1243</a>)",
|
||||
"(#54321)(#1243)", "(<a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a>)(<a href=\"https://someurl.com/someuser/somerepo/1243\">#1243</a>)",
|
||||
"text #54321 test #1243 issue", "text <a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a> test <a href=\"https://someurl.com/someuser/somerepo/1243\">#1243</a> issue",
|
||||
"#1 (#4321) test", "<a href=\"https://someurl.com/someuser/somerepo/1\">#1</a> (<a href=\"https://someurl.com/someuser/somerepo/4321\">#4321</a>) test",
|
||||
}
|
||||
|
||||
for i := 0; i < len(testCases); i += 2 {
|
||||
So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
|
||||
}
|
||||
})
|
||||
})
|
||||
Convey("To an external issue tracker with alphanumeric style", func() {
|
||||
metas = make(map[string]string)
|
||||
metas["format"] = "https://someurl.com/{user}/{repo}/?b={index}"
|
||||
metas["user"] = "someuser"
|
||||
metas["repo"] = "somerepo"
|
||||
metas["style"] = ISSUE_NAME_STYLE_ALPHANUMERIC
|
||||
Convey("It should not render anything when there are no mentions", func() {
|
||||
testCases := []string{
|
||||
"",
|
||||
"this is a test",
|
||||
"test 123 123 1234",
|
||||
"#",
|
||||
"##1234",
|
||||
"# 123",
|
||||
"#abcd",
|
||||
"test #123",
|
||||
"abc-1234", // issue prefix must be capital
|
||||
"ABc-1234", // issue prefix must be _all_ capital
|
||||
"ABCDEFGHIJK-1234", // the limit is 10 characters in the prefix
|
||||
"ABC1234", // dash is required
|
||||
"test ABC- test", // number is required
|
||||
"test -1234 test", // prefix is required
|
||||
"testABC-123 test", // leading space is required
|
||||
"test ABC-123test", // trailing space is required
|
||||
"ABC-0123", // no leading zero
|
||||
}
|
||||
|
||||
for i := 0; i < len(testCases); i += 2 {
|
||||
So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i])
|
||||
}
|
||||
})
|
||||
Convey("It should render freestanding issue mention", func() {
|
||||
testCases := []string{
|
||||
"OTT-1234 test", "<a href=\"https://someurl.com/someuser/somerepo/?b=OTT-1234\">OTT-1234</a> test",
|
||||
"test T-12 issue", "test <a href=\"https://someurl.com/someuser/somerepo/?b=T-12\">T-12</a> issue",
|
||||
"test issue ABCDEFGHIJ-1234567890", "test issue <a href=\"https://someurl.com/someuser/somerepo/?b=ABCDEFGHIJ-1234567890\">ABCDEFGHIJ-1234567890</a>",
|
||||
"A-1 test", "<a href=\"https://someurl.com/someuser/somerepo/?b=A-1\">A-1</a> test",
|
||||
"test ZED-1 issue", "test <a href=\"https://someurl.com/someuser/somerepo/?b=ZED-1\">ZED-1</a> issue",
|
||||
"test issue DEED-7154", "test issue <a href=\"https://someurl.com/someuser/somerepo/?b=DEED-7154\">DEED-7154</a>",
|
||||
}
|
||||
for i := 0; i < len(testCases); i += 2 {
|
||||
So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
|
||||
}
|
||||
})
|
||||
Convey("It should render issue mention in parentheses", func() {
|
||||
testCases := []string{
|
||||
"(ABG-124 issue)", "(<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a> issue)",
|
||||
"test (ABG-124) issue", "test (<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a>) issue",
|
||||
"test (ABG-124 extra) issue", "test (<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a> extra) issue",
|
||||
"test (ABG-124 issue)", "test (<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a> issue)",
|
||||
"test (ABG-124)", "test (<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a>)",
|
||||
}
|
||||
|
||||
for i := 0; i < len(testCases); i += 2 {
|
||||
So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
|
||||
}
|
||||
})
|
||||
Convey("It should render multiple issue mentions in the same line", func() {
|
||||
testCases := []string{
|
||||
"ABG-124 OTT-4321", "<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a> <a href=\"https://someurl.com/someuser/somerepo/?b=OTT-4321\">OTT-4321</a>",
|
||||
"test ABG-124 OTT-4321", "test <a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a> <a href=\"https://someurl.com/someuser/somerepo/?b=OTT-4321\">OTT-4321</a>",
|
||||
"(ABG-124 OTT-4321)", "(<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a> <a href=\"https://someurl.com/someuser/somerepo/?b=OTT-4321\">OTT-4321</a>)",
|
||||
"(ABG-124)(OTT-4321)", "(<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a>)(<a href=\"https://someurl.com/someuser/somerepo/?b=OTT-4321\">OTT-4321</a>)",
|
||||
"text ABG-124 test OTT-4321 issue", "text <a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a> test <a href=\"https://someurl.com/someuser/somerepo/?b=OTT-4321\">OTT-4321</a> issue",
|
||||
"A-1 (RRE-345) test", "<a href=\"https://someurl.com/someuser/somerepo/?b=A-1\">A-1</a> (<a href=\"https://someurl.com/someuser/somerepo/?b=RRE-345\">RRE-345</a>) test",
|
||||
}
|
||||
|
||||
for i := 0; i < len(testCases); i += 2 {
|
||||
So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Convey("Rendering an issue URL", t, func() {
|
||||
setting.AppUrl = "http://localhost:3000/"
|
||||
htmlFlags := 0
|
||||
htmlFlags |= blackfriday.HTML_SKIP_STYLE
|
||||
htmlFlags |= blackfriday.HTML_OMIT_CONTENTS
|
||||
renderer := &Renderer{
|
||||
Renderer: blackfriday.HtmlRenderer(htmlFlags, "", ""),
|
||||
}
|
||||
buffer := new(bytes.Buffer)
|
||||
Convey("To the internal issue tracker", func() {
|
||||
Convey("It should render valid issue URLs", func() {
|
||||
testCases := []string{
|
||||
"http://localhost:3000/user/repo/issues/3333", "<a href=\"http://localhost:3000/user/repo/issues/3333\">#3333</a>",
|
||||
}
|
||||
|
||||
for i := 0; i < len(testCases); i += 2 {
|
||||
renderer.AutoLink(buffer, []byte(testCases[i]), blackfriday.LINK_TYPE_NORMAL)
|
||||
|
||||
line, _ := buffer.ReadString(0)
|
||||
So(line, ShouldEqual, testCases[i+1])
|
||||
}
|
||||
})
|
||||
Convey("It should render but not change non-issue URLs", func() {
|
||||
testCases := []string{
|
||||
"http://1111/2222/ssss-issues/3333?param=blah&blahh=333", "<a href=\"http://1111/2222/ssss-issues/3333?param=blah&blahh=333\">http://1111/2222/ssss-issues/3333?param=blah&blahh=333</a>",
|
||||
"http://test.com/issues/33333", "<a href=\"http://test.com/issues/33333\">http://test.com/issues/33333</a>",
|
||||
"http://test.com/issues/3", "<a href=\"http://test.com/issues/3\">http://test.com/issues/3</a>",
|
||||
"http://issues/333", "<a href=\"http://issues/333\">http://issues/333</a>",
|
||||
"https://issues/333", "<a href=\"https://issues/333\">https://issues/333</a>",
|
||||
"http://tissues/0", "<a href=\"http://tissues/0\">http://tissues/0</a>",
|
||||
}
|
||||
|
||||
for i := 0; i < len(testCases); i += 2 {
|
||||
renderer.AutoLink(buffer, []byte(testCases[i]), blackfriday.LINK_TYPE_NORMAL)
|
||||
|
||||
line, _ := buffer.ReadString(0)
|
||||
So(line, ShouldEqual, testCases[i+1])
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Convey("Rendering a commit URL", t, func() {
|
||||
setting.AppUrl = "http://localhost:3000/"
|
||||
htmlFlags := 0
|
||||
htmlFlags |= blackfriday.HTML_SKIP_STYLE
|
||||
htmlFlags |= blackfriday.HTML_OMIT_CONTENTS
|
||||
renderer := &Renderer{
|
||||
Renderer: blackfriday.HtmlRenderer(htmlFlags, "", ""),
|
||||
}
|
||||
buffer := new(bytes.Buffer)
|
||||
Convey("To the internal issue tracker", func() {
|
||||
Convey("It should correctly convert URLs", func() {
|
||||
testCases := []string{
|
||||
"http://localhost:3000/user/project/commit/d8a994ef243349f321568f9e36d5c3f444b99cae", " <code><a href=\"http://localhost:3000/user/project/commit/d8a994ef243349f321568f9e36d5c3f444b99cae\">d8a994ef24</a></code>",
|
||||
"http://localhost:3000/user/project/commit/d8a994ef243349f321568f9e36d5c3f444b99cae#diff-2", " <code><a href=\"http://localhost:3000/user/project/commit/d8a994ef243349f321568f9e36d5c3f444b99cae#diff-2\">d8a994ef24</a></code>",
|
||||
"https://external-link.gogs.io/gogs/gogs/commit/d8a994ef243349f321568f9e36d5c3f444b99cae#diff-2", "<a href=\"https://external-link.gogs.io/gogs/gogs/commit/d8a994ef243349f321568f9e36d5c3f444b99cae#diff-2\">https://external-link.gogs.io/gogs/gogs/commit/d8a994ef243349f321568f9e36d5c3f444b99cae#diff-2</a>",
|
||||
"https://commit/d8a994ef243349f321568f9e36d5c3f444b99cae", "<a href=\"https://commit/d8a994ef243349f321568f9e36d5c3f444b99cae\">https://commit/d8a994ef243349f321568f9e36d5c3f444b99cae</a>",
|
||||
}
|
||||
|
||||
for i := 0; i < len(testCases); i += 2 {
|
||||
renderer.AutoLink(buffer, []byte(testCases[i]), blackfriday.LINK_TYPE_NORMAL)
|
||||
|
||||
line, _ := buffer.ReadString(0)
|
||||
So(line, ShouldEqual, testCases[i+1])
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -123,6 +123,7 @@ var (
|
||||
AdminNoticePagingNum int
|
||||
AdminOrgPagingNum int
|
||||
ThemeColorMetaTag string
|
||||
MaxDisplayFileSize int64
|
||||
|
||||
// Markdown sttings
|
||||
Markdown struct {
|
||||
@@ -159,18 +160,6 @@ var (
|
||||
SessionConfig session.Options
|
||||
CSRFCookieName = "_csrf"
|
||||
|
||||
// Git settings
|
||||
Git struct {
|
||||
MaxGitDiffLines int
|
||||
GcArgs []string `delim:" "`
|
||||
Timeout struct {
|
||||
Migrate int
|
||||
Mirror int
|
||||
Clone int
|
||||
Pull int
|
||||
} `ini:"git.timeout"`
|
||||
}
|
||||
|
||||
// Cron tasks
|
||||
Cron struct {
|
||||
UpdateMirror struct {
|
||||
@@ -192,6 +181,25 @@ var (
|
||||
} `ini:"cron.check_repo_stats"`
|
||||
}
|
||||
|
||||
// Git settings
|
||||
Git struct {
|
||||
MaxGitDiffLines int
|
||||
MaxGitDiffLineCharacters int
|
||||
MaxGitDiffFiles int
|
||||
GcArgs []string `delim:" "`
|
||||
Timeout struct {
|
||||
Migrate int
|
||||
Mirror int
|
||||
Clone int
|
||||
Pull int
|
||||
} `ini:"git.timeout"`
|
||||
}
|
||||
|
||||
// API settings
|
||||
API struct {
|
||||
MaxResponseItems int
|
||||
}
|
||||
|
||||
// I18n settings
|
||||
Langs, Names []string
|
||||
dateLangs map[string]string
|
||||
@@ -331,7 +339,7 @@ func NewContext() {
|
||||
Domain = sec.Key("DOMAIN").MustString("localhost")
|
||||
HttpAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0")
|
||||
HttpPort = sec.Key("HTTP_PORT").MustString("3000")
|
||||
LocalURL = sec.Key("LOCAL_ROOT_URL").MustString("http://localhost:" + HttpPort + "/")
|
||||
LocalURL = sec.Key("LOCAL_ROOT_URL").MustString(string(Protocol) + "://localhost:" + HttpPort + "/")
|
||||
OfflineMode = sec.Key("OFFLINE_MODE").MustBool()
|
||||
DisableRouterLog = sec.Key("DISABLE_ROUTER_LOG").MustBool()
|
||||
StaticRootPath = sec.Key("STATIC_ROOT_PATH").MustString(workDir)
|
||||
@@ -361,12 +369,6 @@ func NewContext() {
|
||||
} else if err = os.MkdirAll(SSH.KeyTestPath, 0644); err != nil {
|
||||
log.Fatal(4, "Fail to create '%s': %v", SSH.KeyTestPath, err)
|
||||
}
|
||||
|
||||
if !filepath.IsAbs(SSH.KeygenPath) {
|
||||
if _, err := exec.LookPath(SSH.KeygenPath); err != nil {
|
||||
log.Fatal(4, "Fail to test '%s' command: %v (forgotten install?)", SSH.KeygenPath, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SSH.MinimumKeySizeCheck = sec.Key("MINIMUM_KEY_SIZE_CHECK").MustBool()
|
||||
@@ -440,6 +442,7 @@ func NewContext() {
|
||||
ExplorePagingNum = sec.Key("EXPLORE_PAGING_NUM").MustInt(20)
|
||||
IssuePagingNum = sec.Key("ISSUE_PAGING_NUM").MustInt(10)
|
||||
FeedMaxCommitNum = sec.Key("FEED_MAX_COMMIT_NUM").MustInt(5)
|
||||
MaxDisplayFileSize = sec.Key("MAX_DISPLAY_FILE_SIZE").MustInt64(8388608)
|
||||
|
||||
sec = Cfg.Section("ui.admin")
|
||||
AdminUserPagingNum = sec.Key("USER_PAGING_NUM").MustInt(50)
|
||||
@@ -469,10 +472,12 @@ func NewContext() {
|
||||
|
||||
if err = Cfg.Section("markdown").MapTo(&Markdown); err != nil {
|
||||
log.Fatal(4, "Fail to map Markdown settings: %v", err)
|
||||
} else if err = Cfg.Section("git").MapTo(&Git); err != nil {
|
||||
log.Fatal(4, "Fail to map Git settings: %v", err)
|
||||
} else if err = Cfg.Section("cron").MapTo(&Cron); err != nil {
|
||||
log.Fatal(4, "Fail to map Cron settings: %v", err)
|
||||
} else if err = Cfg.Section("git").MapTo(&Git); err != nil {
|
||||
log.Fatal(4, "Fail to map Git settings: %v", err)
|
||||
} else if err = Cfg.Section("api").MapTo(&API); err != nil {
|
||||
log.Fatal(4, "Fail to map API settings: %v", err)
|
||||
}
|
||||
|
||||
Langs = Cfg.Section("i18n").Key("LANGS").Strings(",")
|
||||
@@ -618,16 +623,17 @@ func newSessionService() {
|
||||
|
||||
// Mailer represents mail service.
|
||||
type Mailer struct {
|
||||
QueueLength int
|
||||
Name string
|
||||
Host string
|
||||
From string
|
||||
User, Passwd string
|
||||
DisableHelo bool
|
||||
HeloHostname string
|
||||
SkipVerify bool
|
||||
UseCertificate bool
|
||||
CertFile, KeyFile string
|
||||
QueueLength int
|
||||
Name string
|
||||
Host string
|
||||
From string
|
||||
User, Passwd string
|
||||
DisableHelo bool
|
||||
HeloHostname string
|
||||
SkipVerify bool
|
||||
UseCertificate bool
|
||||
CertFile, KeyFile string
|
||||
EnableHTMLAlternative bool
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -642,17 +648,18 @@ func newMailService() {
|
||||
}
|
||||
|
||||
MailService = &Mailer{
|
||||
QueueLength: sec.Key("SEND_BUFFER_LEN").MustInt(100),
|
||||
Name: sec.Key("NAME").MustString(AppName),
|
||||
Host: sec.Key("HOST").String(),
|
||||
User: sec.Key("USER").String(),
|
||||
Passwd: sec.Key("PASSWD").String(),
|
||||
DisableHelo: sec.Key("DISABLE_HELO").MustBool(),
|
||||
HeloHostname: sec.Key("HELO_HOSTNAME").String(),
|
||||
SkipVerify: sec.Key("SKIP_VERIFY").MustBool(),
|
||||
UseCertificate: sec.Key("USE_CERTIFICATE").MustBool(),
|
||||
CertFile: sec.Key("CERT_FILE").String(),
|
||||
KeyFile: sec.Key("KEY_FILE").String(),
|
||||
QueueLength: sec.Key("SEND_BUFFER_LEN").MustInt(100),
|
||||
Name: sec.Key("NAME").MustString(AppName),
|
||||
Host: sec.Key("HOST").String(),
|
||||
User: sec.Key("USER").String(),
|
||||
Passwd: sec.Key("PASSWD").String(),
|
||||
DisableHelo: sec.Key("DISABLE_HELO").MustBool(),
|
||||
HeloHostname: sec.Key("HELO_HOSTNAME").String(),
|
||||
SkipVerify: sec.Key("SKIP_VERIFY").MustBool(),
|
||||
UseCertificate: sec.Key("USE_CERTIFICATE").MustBool(),
|
||||
CertFile: sec.Key("CERT_FILE").String(),
|
||||
KeyFile: sec.Key("KEY_FILE").String(),
|
||||
EnableHTMLAlternative: sec.Key("ENABLE_HTML_ALTERNATIVE").MustBool(),
|
||||
}
|
||||
MailService.From = sec.Key("FROM").MustString(MailService.User)
|
||||
log.Info("Mail Service Enabled")
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/markdown"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
@@ -97,7 +98,7 @@ func NewFuncMap() []template.FuncMap {
|
||||
"ActionContent2Commits": ActionContent2Commits,
|
||||
"ToUtf8": ToUtf8,
|
||||
"EscapePound": func(str string) string {
|
||||
return strings.Replace(strings.Replace(str, "%", "%25", -1), "#", "%23", -1)
|
||||
return strings.NewReplacer("%", "%25", "#", "%23", " ", "%20").Replace(str)
|
||||
},
|
||||
"RenderCommitMessage": RenderCommitMessage,
|
||||
"ThemeColorMetaTag": func() string {
|
||||
@@ -240,7 +241,7 @@ func ActionIcon(opType int) string {
|
||||
case 7: // New pull request
|
||||
return "git-pull-request"
|
||||
case 10: // Comment issue
|
||||
return "comment"
|
||||
return "comment-discussion"
|
||||
case 11: // Merge pull request
|
||||
return "git-merge"
|
||||
case 12, 14: // Close issue or pull request
|
||||
@@ -255,7 +256,7 @@ func ActionIcon(opType int) string {
|
||||
func ActionContent2Commits(act Actioner) *models.PushCommits {
|
||||
push := models.NewPushCommits()
|
||||
if err := json.Unmarshal([]byte(act.GetContent()), push); err != nil {
|
||||
return nil
|
||||
log.Error(4, "json.Unmarshal:\n%s\nERROR: %v", act.GetContent(), err)
|
||||
}
|
||||
return push
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os"
|
||||
)
|
||||
|
||||
func CurrentUsername() string {
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
4
public/assets/font-awesome-4.6.3/css/font-awesome.min.css
vendored
Normal file
4
public/assets/font-awesome-4.6.3/css/font-awesome.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
public/assets/font-awesome-4.6.3/fonts/FontAwesome.otf
Normal file
BIN
public/assets/font-awesome-4.6.3/fonts/FontAwesome.otf
Normal file
Binary file not shown.
BIN
public/assets/font-awesome-4.6.3/fonts/fontawesome-webfont.eot
Normal file
BIN
public/assets/font-awesome-4.6.3/fonts/fontawesome-webfont.eot
Normal file
Binary file not shown.
@@ -169,7 +169,7 @@
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" />
|
||||
<glyph unicode="" d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5 q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1664" d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91 t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96 q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" />
|
||||
<glyph unicode="" d="M394 184q-8 -9 -20 3q-13 11 -4 19q8 9 20 -3q12 -11 4 -19zM352 245q9 -12 0 -19q-8 -6 -17 7t0 18q9 7 17 -6zM291 305q-5 -7 -13 -2q-10 5 -7 12q3 5 13 2q10 -5 7 -12zM322 271q-6 -7 -16 3q-9 11 -2 16q6 6 16 -3q9 -11 2 -16zM451 159q-4 -12 -19 -6q-17 4 -13 15 t19 7q16 -5 13 -16zM514 154q0 -11 -16 -11q-17 -2 -17 11q0 11 16 11q17 2 17 -11zM572 164q2 -10 -14 -14t-18 8t14 15q16 2 18 -9zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-224q-16 0 -24.5 1t-19.5 5t-16 14.5t-5 27.5v239q0 97 -52 142q57 6 102.5 18t94 39 t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103 q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -103t0.5 -68q0 -22 -11 -33.5t-22 -13t-33 -1.5 h-224q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
|
||||
<glyph unicode="" d="M519 336q4 6 -3 13q-9 7 -14 2q-4 -6 3 -13q9 -7 14 -2zM491 377q-5 7 -12 4q-6 -4 0 -12q7 -8 12 -5q6 4 0 13zM450 417q2 4 -5 8q-7 2 -8 -2q-3 -5 4 -8q8 -2 9 2zM471 394q2 1 1.5 4.5t-3.5 5.5q-6 7 -10 3t1 -11q6 -6 11 -2zM557 319q2 7 -9 11q-9 3 -13 -4 q-2 -7 9 -11q9 -3 13 4zM599 316q0 8 -12 8q-10 0 -10 -8t11 -8t11 8zM638 323q-2 7 -13 5t-9 -9q2 -8 12 -6t10 10zM1280 640q0 212 -150 362t-362 150t-362 -150t-150 -362q0 -167 98 -300.5t252 -185.5q18 -3 26.5 5t8.5 20q0 52 -1 95q-6 -1 -15.5 -2.5t-35.5 -2t-48 4 t-43.5 20t-29.5 41.5q-23 59 -57 74q-2 1 -4.5 3.5l-8 8t-7 9.5t4 7.5t19.5 3.5q6 0 15 -2t30 -15.5t33 -35.5q16 -28 37.5 -42t43.5 -14t38 3.5t30 9.5q7 47 33 69q-49 6 -86 18.5t-73 39t-55.5 76t-19.5 119.5q0 79 53 137q-24 62 5 136q19 6 54.5 -7.5t60.5 -29.5l26 -16 q58 17 128 17t128 -17q11 7 28.5 18t55.5 26t57 9q29 -74 5 -136q53 -58 53 -137q0 -57 -14 -100.5t-35.5 -70t-53.5 -44.5t-62.5 -26t-68.5 -12q35 -31 35 -95q0 -40 -0.5 -89t-0.5 -51q0 -12 8.5 -20t26.5 -5q154 52 252 185.5t98 300.5zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1664" d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92 t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" />
|
||||
<glyph unicode="" d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5 q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44 q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5 q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -10 1 -18.5t3 -17t4 -13.5t6.5 -16t6.5 -17q16 -40 25 -118.5t9 -136.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1408" d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -52.5 3.5t-57.5 12.5t-47.5 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-128 79 -264.5 215.5t-215.5 264.5q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47.5t-12.5 57.5t-3.5 52.5 q0 92 51 186q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174 q2 -1 19 -11.5t24 -14t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" />
|
||||
@@ -178,7 +178,7 @@
|
||||
<glyph unicode="" d="M1280 343q0 11 -2 16q-3 8 -38.5 29.5t-88.5 49.5l-53 29q-5 3 -19 13t-25 15t-21 5q-18 0 -47 -32.5t-57 -65.5t-44 -33q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170.5 126.5t-126.5 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5t-3.5 16.5q0 13 20.5 33.5t45 38.5 t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5t320.5 -216.5q6 -2 30 -11t33 -12.5 t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1664" d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41 q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" />
|
||||
<glyph unicode="" horiz-adv-x="1024" d="M959 1524v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12z" />
|
||||
<glyph unicode="" d="M1536 640q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -39.5 7t-12.5 30v211q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5 q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23 q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -89t0.5 -54q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
|
||||
<glyph unicode="" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -40 7t-13 30q0 3 0.5 76.5t0.5 134.5q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 119 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24 q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-85 13.5q-45 -113 -8 -204q-79 -87 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-39 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5 t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -88.5t0.5 -54.5q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103zM291 305q3 7 -7 12 q-10 3 -13 -2q-3 -7 7 -12q9 -6 13 2zM322 271q7 5 -2 16q-10 9 -16 3q-7 -5 2 -16q10 -10 16 -3zM352 226q9 7 0 19q-8 13 -17 6q-9 -5 0 -18t17 -7zM394 184q8 8 -4 19q-12 12 -20 3q-9 -8 4 -19q12 -12 20 -3zM451 159q3 11 -13 16q-15 4 -19 -7t13 -15q15 -6 19 6z M514 154q0 13 -17 11q-16 0 -16 -11q0 -13 17 -11q16 0 16 11zM572 164q-2 11 -18 9q-16 -3 -14 -15t18 -8t14 14z" />
|
||||
<glyph unicode="" horiz-adv-x="1664" d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5 t316.5 -131.5t131.5 -316.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1920" d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608 q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" />
|
||||
<glyph unicode="" horiz-adv-x="1408" d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5 t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294 q187 -186 294 -425.5t120 -501.5z" />
|
||||
@@ -363,7 +363,7 @@
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M1280 640q0 37 -30 54l-512 320q-31 20 -65 2q-33 -18 -33 -56v-640q0 -38 33 -56q16 -8 31 -8q20 0 34 10l512 320q30 17 30 54zM1792 640q0 -96 -1 -150t-8.5 -136.5t-22.5 -147.5q-16 -73 -69 -123t-124 -58q-222 -25 -671 -25t-671 25q-71 8 -124.5 58t-69.5 123 q-14 65 -21.5 147.5t-8.5 136.5t-1 150t1 150t8.5 136.5t22.5 147.5q16 73 69 123t124 58q222 25 671 25t671 -25q71 -8 124.5 -58t69.5 -123q14 -65 21.5 -147.5t8.5 -136.5t1 -150z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M402 829l494 -305l-342 -285l-490 319zM1388 274v-108l-490 -293v-1l-1 1l-1 -1v1l-489 293v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284zM554 1418l342 -285l-494 -304l-338 270zM1390 829l338 -271l-489 -319l-343 285zM1239 1418l489 -319l-338 -270l-494 304z" />
|
||||
<glyph unicode="" d="M1289 -96h-1118v480h-160v-640h1438v640h-160v-480zM347 428l33 157l783 -165l-33 -156zM450 802l67 146l725 -339l-67 -145zM651 1158l102 123l614 -513l-102 -123zM1048 1536l477 -641l-128 -96l-477 641zM330 65v159h800v-159h-800z" />
|
||||
<glyph unicode="" d="M1362 110v648h-135q20 -63 20 -131q0 -126 -64 -232.5t-174 -168.5t-240 -62q-197 0 -337 135.5t-140 327.5q0 68 20 131h-141v-648q0 -26 17.5 -43.5t43.5 -17.5h1069q25 0 43 17.5t18 43.5zM1078 643q0 124 -90.5 211.5t-218.5 87.5q-127 0 -217.5 -87.5t-90.5 -211.5 t90.5 -211.5t217.5 -87.5q128 0 218.5 87.5t90.5 211.5zM1362 1003v165q0 28 -20 48.5t-49 20.5h-174q-29 0 -49 -20.5t-20 -48.5v-165q0 -29 20 -49t49 -20h174q29 0 49 20t20 49zM1536 1211v-1142q0 -81 -58 -139t-139 -58h-1142q-81 0 -139 58t-58 139v1142q0 81 58 139 t139 58h1142q81 0 139 -58t58 -139z" />
|
||||
<glyph unicode="" d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1162 640q0 -164 -115 -279t-279 -115t-279 115t-115 279t115 279t279 115t279 -115t115 -279zM1270 1050q0 -38 -27 -65t-65 -27t-65 27t-27 65t27 65t65 27t65 -27t27 -65zM768 1270 q-7 0 -76.5 0.5t-105.5 0t-96.5 -3t-103 -10t-71.5 -18.5q-50 -20 -88 -58t-58 -88q-11 -29 -18.5 -71.5t-10 -103t-3 -96.5t0 -105.5t0.5 -76.5t-0.5 -76.5t0 -105.5t3 -96.5t10 -103t18.5 -71.5q20 -50 58 -88t88 -58q29 -11 71.5 -18.5t103 -10t96.5 -3t105.5 0t76.5 0.5 t76.5 -0.5t105.5 0t96.5 3t103 10t71.5 18.5q50 20 88 58t58 88q11 29 18.5 71.5t10 103t3 96.5t0 105.5t-0.5 76.5t0.5 76.5t0 105.5t-3 96.5t-10 103t-18.5 71.5q-20 50 -58 88t-88 58q-29 11 -71.5 18.5t-103 10t-96.5 3t-105.5 0t-76.5 -0.5zM1536 640q0 -229 -5 -317 q-10 -208 -124 -322t-322 -124q-88 -5 -317 -5t-317 5q-208 10 -322 124t-124 322q-5 88 -5 317t5 317q10 208 124 322t322 124q88 5 317 5t317 -5q208 -10 322 -124t124 -322q5 -88 5 -317z" />
|
||||
<glyph unicode="" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM698 640q0 88 -62 150t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150zM1262 640q0 88 -62 150 t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150z" />
|
||||
<glyph unicode="" d="M768 914l201 -306h-402zM1133 384h94l-459 691l-459 -691h94l104 160h522zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1408" d="M815 677q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82t52 58q36 18 72.5 12t64 -35.5t27.5 -67.5zM926 698q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5q4 -91 77.5 -155t165.5 -56q91 8 152 84t50 168zM1165 1240q-20 27 -56 44.5t-58 22 t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5zM1222 205q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18 t-76.5 27t-73 43.5t-52 61.5q-25 96 -57 292l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37zM1403 1166q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34t-6 39.5 t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54z" />
|
||||
@@ -484,7 +484,7 @@
|
||||
<glyph unicode="" horiz-adv-x="2048" d="M1024 13q-20 0 -93 73.5t-73 93.5q0 32 62.5 54t103.5 22t103.5 -22t62.5 -54q0 -20 -73 -93.5t-93 -73.5zM1294 284q-2 0 -40 25t-101.5 50t-128.5 25t-128.5 -25t-101 -50t-40.5 -25q-18 0 -93.5 75t-75.5 93q0 13 10 23q78 77 196 121t233 44t233 -44t196 -121 q10 -10 10 -23q0 -18 -75.5 -93t-93.5 -75zM1567 556q-11 0 -23 8q-136 105 -252 154.5t-268 49.5q-85 0 -170.5 -22t-149 -53t-113.5 -62t-79 -53t-31 -22q-17 0 -92 75t-75 93q0 12 10 22q132 132 320 205t380 73t380 -73t320 -205q10 -10 10 -22q0 -18 -75 -93t-92 -75z M1838 827q-11 0 -22 9q-179 157 -371.5 236.5t-420.5 79.5t-420.5 -79.5t-371.5 -236.5q-11 -9 -22 -9q-17 0 -92.5 75t-75.5 93q0 13 10 23q187 186 445 288t527 102t527 -102t445 -288q10 -10 10 -23q0 -18 -75.5 -93t-92.5 -75z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M384 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5 t37.5 90.5zM384 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 768q0 53 -37.5 90.5t-90.5 37.5 t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1536 0v384q0 52 -38 90t-90 38t-90 -38t-38 -90v-384q0 -52 38 -90t90 -38t90 38t38 90zM1152 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z M1536 1088v256q0 26 -19 45t-45 19h-1280q-26 0 -45 -19t-19 -45v-256q0 -26 19 -45t45 -19h1280q26 0 45 19t19 45zM1536 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1408v-1536q0 -52 -38 -90t-90 -38 h-1408q-52 0 -90 38t-38 90v1536q0 52 38 90t90 38h1408q52 0 90 -38t38 -90z" />
|
||||
<glyph unicode="" d="M1519 890q18 -84 -4 -204q-87 -444 -565 -444h-44q-25 0 -44 -16.5t-24 -42.5l-4 -19l-55 -346l-2 -15q-5 -26 -24.5 -42.5t-44.5 -16.5h-251q-21 0 -33 15t-9 36q9 56 26.5 168t26.5 168t27 167.5t27 167.5q5 37 43 37h131q133 -2 236 21q175 39 287 144q102 95 155 246 q24 70 35 133q1 6 2.5 7.5t3.5 1t6 -3.5q79 -59 98 -162zM1347 1172q0 -107 -46 -236q-80 -233 -302 -315q-113 -40 -252 -42q0 -1 -90 -1l-90 1q-100 0 -118 -96q-2 -8 -85 -530q-1 -10 -12 -10h-295q-22 0 -36.5 16.5t-11.5 38.5l232 1471q5 29 27.5 48t51.5 19h598 q34 0 97.5 -13t111.5 -32q107 -41 163.5 -123t56.5 -196z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M602 949q19 -61 31 -123.5t17 -141.5t-14 -159t-62 -145q-21 81 -67 157t-95.5 127t-99 90.5t-78.5 57.5t-33 19q-62 34 -81.5 100t14.5 128t101 81.5t129 -14.5q138 -83 238 -177zM927 1236q11 -25 20.5 -46t36.5 -100.5t42.5 -150.5t25.5 -179.5t0 -205.5t-47.5 -209.5 t-105.5 -208.5q-51 -72 -138 -72q-54 0 -98 31q-57 40 -69 109t28 127q60 85 81 195t13 199.5t-32 180.5t-39 128t-22 52q-31 63 -8.5 129.5t85.5 97.5q34 17 75 17q47 0 88.5 -25t63.5 -69zM1248 567q-17 -160 -72 -311q-17 131 -63 246q25 174 -5 361q-27 178 -94 342 q114 -90 212 -211q9 -37 15 -80q26 -179 7 -347zM1520 1440q9 -17 23.5 -49.5t43.5 -117.5t50.5 -178t34 -227.5t5 -269t-47 -300t-112.5 -323.5q-22 -48 -66 -75.5t-95 -27.5q-39 0 -74 16q-67 31 -92.5 100t4.5 136q58 126 90 257.5t37.5 239.5t-3.5 213.5t-26.5 180.5 t-38.5 138.5t-32.5 90t-15.5 32.5q-34 65 -11.5 135.5t87.5 104.5q37 20 81 20q49 0 91.5 -25.5t66.5 -70.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M441 864q32 0 52 -26q266 -364 362 -774h-446q-127 441 -367 749q-12 16 -3 33.5t29 17.5h373zM1000 507q-49 -199 -125 -393q-79 310 -256 594q40 221 44 449q211 -340 337 -650zM1099 1216q235 -324 384.5 -698.5t184.5 -773.5h-451q-41 665 -553 1472h435zM1792 640 q0 -424 -101 -812q-67 560 -359 1083q-25 301 -106 584q-4 16 5.5 28.5t25.5 12.5h359q21 0 38.5 -13t22.5 -33q115 -409 115 -850z" />
|
||||
<glyph unicode="" horiz-adv-x="2304" d="M1975 546h-138q14 37 66 179l3 9q4 10 10 26t9 26l12 -55zM531 611l-58 295q-11 54 -75 54h-268l-2 -13q311 -79 403 -336zM710 960l-162 -438l-17 89q-26 70 -85 129.5t-131 88.5l135 -510h175l261 641h-176zM849 318h166l104 642h-166zM1617 944q-69 27 -149 27 q-123 0 -201 -59t-79 -153q-1 -102 145 -174q48 -23 67 -41t19 -39q0 -30 -30 -46t-69 -16q-86 0 -156 33l-22 11l-23 -144q74 -34 185 -34q130 -1 208.5 59t80.5 160q0 106 -140 174q-49 25 -71 42t-22 38q0 22 24.5 38.5t70.5 16.5q70 1 124 -24l15 -8zM2042 960h-128 q-65 0 -87 -54l-246 -588h174l35 96h212q5 -22 20 -96h154zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
|
||||
<glyph unicode="" horiz-adv-x="2304" d="M671 603h-13q-47 0 -47 -32q0 -22 20 -22q17 0 28 15t12 39zM1066 639h62v3q1 4 0.5 6.5t-1 7t-2 8t-4.5 6.5t-7.5 5t-11.5 2q-28 0 -36 -38zM1606 603h-12q-48 0 -48 -32q0 -22 20 -22q17 0 28 15t12 39zM1925 629q0 41 -30 41q-19 0 -31 -20t-12 -51q0 -42 28 -42 q20 0 32.5 20t12.5 52zM480 770h87l-44 -262h-56l32 201l-71 -201h-39l-4 200l-34 -200h-53l44 262h81l2 -163zM733 663q0 -6 -4 -42q-16 -101 -17 -113h-47l1 22q-20 -26 -58 -26q-23 0 -37.5 16t-14.5 42q0 39 26 60.5t73 21.5q14 0 23 -1q0 3 0.5 5.5t1 4.5t0.5 3 q0 20 -36 20q-29 0 -59 -10q0 4 7 48q38 11 67 11q74 0 74 -62zM889 721l-8 -49q-22 3 -41 3q-27 0 -27 -17q0 -8 4.5 -12t21.5 -11q40 -19 40 -60q0 -72 -87 -71q-34 0 -58 6q0 2 7 49q29 -8 51 -8q32 0 32 19q0 7 -4.5 11.5t-21.5 12.5q-43 20 -43 59q0 72 84 72 q30 0 50 -4zM977 721h28l-7 -52h-29q-2 -17 -6.5 -40.5t-7 -38.5t-2.5 -18q0 -16 19 -16q8 0 16 2l-8 -47q-21 -7 -40 -7q-43 0 -45 47q0 12 8 56q3 20 25 146h55zM1180 648q0 -23 -7 -52h-111q-3 -22 10 -33t38 -11q30 0 58 14l-9 -54q-30 -8 -57 -8q-95 0 -95 95 q0 55 27.5 90.5t69.5 35.5q35 0 55.5 -21t20.5 -56zM1319 722q-13 -23 -22 -62q-22 2 -31 -24t-25 -128h-56l3 14q22 130 29 199h51l-3 -33q14 21 25.5 29.5t28.5 4.5zM1506 763l-9 -57q-28 14 -50 14q-31 0 -51 -27.5t-20 -70.5q0 -30 13.5 -47t38.5 -17q21 0 48 13 l-10 -59q-28 -8 -50 -8q-45 0 -71.5 30.5t-26.5 82.5q0 70 35.5 114.5t91.5 44.5q26 0 61 -13zM1668 663q0 -18 -4 -42q-13 -79 -17 -113h-46l1 22q-20 -26 -59 -26q-23 0 -37 16t-14 42q0 39 25.5 60.5t72.5 21.5q15 0 23 -1q2 7 2 13q0 20 -36 20q-29 0 -59 -10q0 4 8 48 q38 11 67 11q73 0 73 -62zM1809 722q-14 -24 -21 -62q-23 2 -31.5 -23t-25.5 -129h-56l3 14q19 104 29 199h52q0 -11 -4 -33q15 21 26.5 29.5t27.5 4.5zM1950 770h56l-43 -262h-53l3 19q-23 -23 -52 -23q-31 0 -49.5 24t-18.5 64q0 53 27.5 92t64.5 39q31 0 53 -29z M2061 640q0 148 -72.5 273t-198 198t-273.5 73q-181 0 -328 -110q127 -116 171 -284h-50q-44 150 -158 253q-114 -103 -158 -253h-50q44 168 171 284q-147 110 -328 110q-148 0 -273.5 -73t-198 -198t-72.5 -273t72.5 -273t198 -198t273.5 -73q181 0 328 110 q-120 111 -165 264h50q46 -138 152 -233q106 95 152 233h50q-45 -153 -165 -264q147 -110 328 -110q148 0 273.5 73t198 198t72.5 273zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
|
||||
<glyph unicode="" horiz-adv-x="2304" d="M313 759q0 -51 -36 -84q-29 -26 -89 -26h-17v220h17q61 0 89 -27q36 -31 36 -83zM2089 824q0 -52 -64 -52h-19v101h20q63 0 63 -49zM380 759q0 74 -50 120.5t-129 46.5h-95v-333h95q74 0 119 38q60 51 60 128zM410 593h65v333h-65v-333zM730 694q0 40 -20.5 62t-75.5 42 q-29 10 -39.5 19t-10.5 23q0 16 13.5 26.5t34.5 10.5q29 0 53 -27l34 44q-41 37 -98 37q-44 0 -74 -27.5t-30 -67.5q0 -35 18 -55.5t64 -36.5q37 -13 45 -19q19 -12 19 -34q0 -20 -14 -33.5t-36 -13.5q-48 0 -71 44l-42 -40q44 -64 115 -64q51 0 83 30.5t32 79.5zM1008 604 v77q-37 -37 -78 -37q-49 0 -80.5 32.5t-31.5 82.5q0 48 31.5 81.5t77.5 33.5q43 0 81 -38v77q-40 20 -80 20q-74 0 -125.5 -50.5t-51.5 -123.5t51 -123.5t125 -50.5q42 0 81 19zM2240 0v527q-65 -40 -144.5 -84t-237.5 -117t-329.5 -137.5t-417.5 -134.5t-504 -118h1569 q26 0 45 19t19 45zM1389 757q0 75 -53 128t-128 53t-128 -53t-53 -128t53 -128t128 -53t128 53t53 128zM1541 584l144 342h-71l-90 -224l-89 224h-71l142 -342h35zM1714 593h184v56h-119v90h115v56h-115v74h119v57h-184v-333zM2105 593h80l-105 140q76 16 76 94q0 47 -31 73 t-87 26h-97v-333h65v133h9zM2304 1274v-1268q0 -56 -38.5 -95t-93.5 -39h-2040q-55 0 -93.5 39t-38.5 95v1268q0 56 38.5 95t93.5 39h2040q55 0 93.5 -39t38.5 -95z" />
|
||||
@@ -626,7 +626,7 @@
|
||||
<glyph unicode="" horiz-adv-x="2304" d="M0 32v608h2304v-608q0 -66 -47 -113t-113 -47h-1984q-66 0 -113 47t-47 113zM640 256v-128h384v128h-384zM256 256v-128h256v128h-256zM2144 1408q66 0 113 -47t47 -113v-224h-2304v224q0 66 47 113t113 47h1984z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M1549 857q55 0 85.5 -28.5t30.5 -83.5t-34 -82t-91 -27h-136v-177h-25v398h170zM1710 267l-4 -11l-5 -10q-113 -230 -330.5 -366t-474.5 -136q-182 0 -348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71q244 0 454.5 -124t329.5 -338l2 -4l8 -16 q-30 -15 -136.5 -68.5t-163.5 -84.5q-6 -3 -479 -268q384 -183 799 -366zM896 -234q250 0 462.5 132.5t322.5 357.5l-287 129q-72 -140 -206 -222t-292 -82q-151 0 -280 75t-204 204t-75 280t75 280t204 204t280 75t280 -73.5t204 -204.5l280 143q-116 208 -321 329 t-443 121q-119 0 -232.5 -31.5t-209 -87.5t-176.5 -137t-137 -176.5t-87.5 -209t-31.5 -232.5t31.5 -232.5t87.5 -209t137 -176.5t176.5 -137t209 -87.5t232.5 -31.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M1427 827l-614 386l92 151h855zM405 562l-184 116v858l1183 -743zM1424 697l147 -95v-858l-532 335zM1387 718l-500 -802h-855l356 571z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M640 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1152 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1664 496v-752h-640v320q0 80 -56 136t-136 56t-136 -56t-56 -136v-320h-640v752q0 16 16 16h96 q16 0 16 -16v-112h128v624q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h16v393q-32 19 -32 55q0 26 19 45t45 19t45 -19t19 -45q0 -36 -32 -55v-9h272q16 0 16 -16v-224q0 -16 -16 -16h-272v-128h16q16 0 16 -16v-112h128 v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-624h128v112q0 16 16 16h96q16 0 16 -16z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M640 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1152 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1664 496v-752h-640v320q0 80 -56 136t-136 56t-136 -56t-56 -136v-320h-640v752q0 16 16 16h96 q16 0 16 -16v-112h128v624q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 6 2.5 9.5t8.5 5t9.5 2t11.5 0t9 -0.5v391q-32 15 -32 50q0 23 16.5 39t38.5 16t38.5 -16t16.5 -39q0 -35 -32 -50v-17q45 10 83 10q21 0 59.5 -7.5t54.5 -7.5 q17 0 47 7.5t37 7.5q16 0 16 -16v-210q0 -15 -35 -21.5t-62 -6.5q-18 0 -54.5 7.5t-55.5 7.5q-40 0 -90 -12v-133q1 0 9 0.5t11.5 0t9.5 -2t8.5 -5t2.5 -9.5v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-624h128v112q0 16 16 16h96 q16 0 16 -16z" />
|
||||
<glyph unicode="" horiz-adv-x="2304" d="M2288 731q16 -8 16 -27t-16 -27l-320 -192q-8 -5 -16 -5q-9 0 -16 4q-16 10 -16 28v128h-858q37 -58 83 -165q16 -37 24.5 -55t24 -49t27 -47t27 -34t31.5 -26t33 -8h96v96q0 14 9 23t23 9h320q14 0 23 -9t9 -23v-320q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v96h-96 q-32 0 -61 10t-51 23.5t-45 40.5t-37 46t-33.5 57t-28.5 57.5t-28 60.5q-23 53 -37 81.5t-36 65t-44.5 53.5t-46.5 17h-360q-22 -84 -91 -138t-157 -54q-106 0 -181 75t-75 181t75 181t181 75q88 0 157 -54t91 -138h104q24 0 46.5 17t44.5 53.5t36 65t37 81.5q19 41 28 60.5 t28.5 57.5t33.5 57t37 46t45 40.5t51 23.5t61 10h107q21 57 70 92.5t111 35.5q80 0 136 -56t56 -136t-56 -136t-136 -56q-62 0 -111 35.5t-70 92.5h-107q-17 0 -33 -8t-31.5 -26t-27 -34t-27 -47t-24 -49t-24.5 -55q-46 -107 -83 -165h1114v128q0 18 16 28t32 -1z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M1150 774q0 -56 -39.5 -95t-95.5 -39h-253v269h253q56 0 95.5 -39.5t39.5 -95.5zM1329 774q0 130 -91.5 222t-222.5 92h-433v-896h180v269h253q130 0 222 91.5t92 221.5zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348 t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
|
||||
<glyph unicode="" horiz-adv-x="2304" d="M1645 438q0 59 -34 106.5t-87 68.5q-7 -45 -23 -92q-7 -24 -27.5 -38t-44.5 -14q-12 0 -24 3q-31 10 -45 38.5t-4 58.5q23 71 23 143q0 123 -61 227.5t-166 165.5t-228 61q-134 0 -247 -73t-167 -194q108 -28 188 -106q22 -23 22 -55t-22 -54t-54 -22t-55 22 q-75 75 -180 75q-106 0 -181 -74.5t-75 -180.5t75 -180.5t181 -74.5h1046q79 0 134.5 55.5t55.5 133.5zM1798 438q0 -142 -100.5 -242t-242.5 -100h-1046q-169 0 -289 119.5t-120 288.5q0 153 100 267t249 136q62 184 221 298t354 114q235 0 408.5 -158.5t196.5 -389.5 q116 -25 192.5 -118.5t76.5 -214.5zM2048 438q0 -175 -97 -319q-23 -33 -64 -33q-24 0 -43 13q-26 17 -32 48.5t12 57.5q71 104 71 233t-71 233q-18 26 -12 57t32 49t57.5 11.5t49.5 -32.5q97 -142 97 -318zM2304 438q0 -244 -134 -443q-23 -34 -64 -34q-23 0 -42 13 q-26 18 -32.5 49t11.5 57q108 164 108 358q0 195 -108 357q-18 26 -11.5 57.5t32.5 48.5q26 18 57 12t49 -33q134 -198 134 -442z" />
|
||||
@@ -641,15 +641,45 @@
|
||||
<glyph unicode="" d="M841 483l148 -148l-149 -149zM840 1094l149 -149l-148 -148zM710 -130l464 464l-306 306l306 306l-464 464v-611l-255 255l-93 -93l320 -321l-320 -321l93 -93l255 255v-611zM1429 640q0 -209 -32 -365.5t-87.5 -257t-140.5 -162.5t-181.5 -86.5t-219.5 -24.5 t-219.5 24.5t-181.5 86.5t-140.5 162.5t-87.5 257t-32 365.5t32 365.5t87.5 257t140.5 162.5t181.5 86.5t219.5 24.5t219.5 -24.5t181.5 -86.5t140.5 -162.5t87.5 -257t32 -365.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1024" d="M596 113l173 172l-173 172v-344zM596 823l173 172l-173 172v-344zM628 640l356 -356l-539 -540v711l-297 -296l-108 108l372 373l-372 373l108 108l297 -296v711l539 -540z" />
|
||||
<glyph unicode="" d="M1280 256q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM512 1024q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5 t112.5 -271.5zM1440 1344q0 -20 -13 -38l-1056 -1408q-19 -26 -51 -26h-160q-26 0 -45 19t-19 45q0 20 13 38l1056 1408q19 26 51 26h160q26 0 45 -19t19 -45zM768 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5 t271.5 -112.5t112.5 -271.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M104 830l792 -1015l-868 630q-18 13 -25 34.5t0 42.5l101 308v0zM566 830h660l-330 -1015v0zM368 1442l198 -612h-462l198 612q8 23 33 23t33 -23zM1688 830l101 -308q7 -21 0 -42.5t-25 -34.5l-868 -630l792 1015v0zM1688 830h-462l198 612q8 23 33 23t33 -23z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M384 704h160v224h-160v-224zM1221 372v92q-104 -36 -243 -38q-135 -1 -259.5 46.5t-220.5 122.5l1 -96q88 -80 212 -128.5t272 -47.5q129 0 238 49zM640 704h640v224h-640v-224zM1792 736q0 -187 -99 -352q89 -102 89 -229q0 -157 -129.5 -268t-313.5 -111 q-122 0 -225 52.5t-161 140.5q-19 -1 -57 -1t-57 1q-58 -88 -161 -140.5t-225 -52.5q-184 0 -313.5 111t-129.5 268q0 127 89 229q-99 165 -99 352q0 209 120 385.5t326.5 279.5t449.5 103t449.5 -103t326.5 -279.5t120 -385.5z" />
|
||||
<glyph unicode="" d="M515 625v-128h-252v128h252zM515 880v-127h-252v127h252zM1273 369v-128h-341v128h341zM1273 625v-128h-672v128h672zM1273 880v-127h-672v127h672zM1408 20v1240q0 8 -6 14t-14 6h-32l-378 -256l-210 171l-210 -171l-378 256h-32q-8 0 -14 -6t-6 -14v-1240q0 -8 6 -14 t14 -6h1240q8 0 14 6t6 14zM553 1130l185 150h-406zM983 1130l221 150h-406zM1536 1260v-1240q0 -62 -43 -105t-105 -43h-1240q-62 0 -105 43t-43 105v1240q0 62 43 105t105 43h1240q62 0 105 -43t43 -105z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M896 720q-104 196 -160 278q-139 202 -347 318q-34 19 -70 36q-89 40 -94 32t34 -38l39 -31q62 -43 112.5 -93.5t94.5 -116.5t70.5 -113t70.5 -131q9 -17 13 -25q44 -84 84 -153t98 -154t115.5 -150t131 -123.5t148.5 -90.5q153 -66 154 -60q1 3 -49 37q-53 36 -81 57 q-77 58 -179 211t-185 310zM549 177q-76 60 -132.5 125t-98 143.5t-71 154.5t-58.5 186t-52 209t-60.5 252t-76.5 289q273 0 497.5 -36t379 -92t271 -144.5t185.5 -172.5t110 -198.5t56 -199.5t12.5 -198.5t-9.5 -173t-20 -143.5t-13 -107l323 -327h-104l-281 285 q-22 -2 -91.5 -14t-121.5 -19t-138 -6t-160.5 17t-167.5 59t-179 111z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M1374 879q-6 26 -28.5 39.5t-48.5 7.5q-261 -62 -401 -62t-401 62q-26 6 -48.5 -7.5t-28.5 -39.5t7.5 -48.5t39.5 -28.5q194 -46 303 -58q-2 -158 -15.5 -269t-26.5 -155.5t-41 -115.5l-9 -21q-10 -25 1 -49t36 -34q9 -4 23 -4q44 0 60 41l8 20q54 139 71 259h42 q17 -120 71 -259l8 -20q16 -41 60 -41q14 0 23 4q25 10 36 34t1 49l-9 21q-28 71 -41 115.5t-26.5 155.5t-15.5 269q109 12 303 58q26 6 39.5 28.5t7.5 48.5zM1024 1024q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z M1600 640q0 -143 -55.5 -273.5t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5zM896 1408q-156 0 -298 -61t-245 -164t-164 -245t-61 -298t61 -298 t164 -245t245 -164t298 -61t298 61t245 164t164 245t61 298t-61 298t-164 245t-245 164t-298 61zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
|
||||
<glyph unicode="" d="M1438 723q34 -35 29 -82l-44 -551q-4 -42 -34.5 -70t-71.5 -28q-6 0 -9 1q-44 3 -72.5 36.5t-25.5 77.5l35 429l-143 -8q55 -113 55 -240q0 -216 -148 -372l-137 137q91 101 91 235q0 145 -102.5 248t-247.5 103q-134 0 -236 -92l-137 138q120 114 284 141l264 300 l-149 87l-181 -161q-33 -30 -77 -27.5t-73 35.5t-26.5 77t34.5 73l239 213q26 23 60 26.5t64 -14.5l488 -283q36 -21 48 -68q17 -67 -26 -117l-205 -232l371 20q49 3 83 -32zM1240 1180q-74 0 -126 52t-52 126t52 126t126 52t126.5 -52t52.5 -126t-52.5 -126t-126.5 -52z M613 -62q106 0 196 61l139 -139q-146 -116 -335 -116q-148 0 -273.5 73t-198.5 198t-73 273q0 188 116 336l139 -139q-60 -88 -60 -197q0 -145 102.5 -247.5t247.5 -102.5z" />
|
||||
<glyph unicode="" d="M880 336v-160q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v160q0 14 9 23t23 9h160q14 0 23 -9t9 -23zM1136 832q0 -50 -15 -90t-45.5 -69t-52 -44t-59.5 -36q-32 -18 -46.5 -28t-26 -24t-11.5 -29v-32q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v68q0 35 10.5 64.5 t24 47.5t39 35.5t41 25.5t44.5 21q53 25 75 43t22 49q0 42 -43.5 71.5t-95.5 29.5q-56 0 -95 -27q-29 -20 -80 -83q-9 -12 -25 -12q-11 0 -19 6l-108 82q-10 7 -12 20t5 23q122 192 349 192q129 0 238.5 -89.5t109.5 -214.5zM768 1280q-130 0 -248.5 -51t-204 -136.5 t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5 t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1408" d="M366 1225q-64 0 -110 45.5t-46 110.5q0 64 46 109.5t110 45.5t109.5 -45.5t45.5 -109.5q0 -65 -45.5 -110.5t-109.5 -45.5zM917 583q0 -50 -30 -67.5t-63.5 -6.5t-47.5 34l-367 438q-7 12 -14 15.5t-11 1.5l-3 -3q-7 -8 4 -21l122 -139l1 -354l-161 -457 q-67 -192 -92 -234q-16 -26 -28 -32q-50 -26 -103 -1q-29 13 -41.5 43t-9.5 57q2 17 197 618l5 416l-85 -164l35 -222q4 -24 -1 -42t-14 -27.5t-19 -16t-17 -7.5l-7 -2q-19 -3 -34.5 3t-24 16t-14 22t-7.5 19.5t-2 9.5l-46 299l211 381q23 34 113 34q75 0 107 -40l424 -521 q7 -5 14 -17l3 -3l-1 -1q7 -13 7 -29zM514 433q43 -113 88.5 -225t69.5 -168l24 -55q36 -93 42 -125q11 -70 -36 -97q-35 -22 -66 -16t-51 22t-29 35h-1q-6 16 -8 25l-124 351zM1338 -159q31 -49 31 -57q0 -5 -3 -7q-9 -5 -14.5 0.5t-15.5 26t-16 30.5q-114 172 -423 661 q3 -1 7 1t7 4l3 2q11 9 11 17z" />
|
||||
<glyph unicode="" horiz-adv-x="2304" d="M504 542h171l-1 265zM1530 641q0 87 -50.5 140t-146.5 53h-54v-388h52q91 0 145 57t54 138zM956 1018l1 -756q0 -14 -9.5 -24t-23.5 -10h-216q-14 0 -23.5 10t-9.5 24v62h-291l-55 -81q-10 -15 -28 -15h-267q-21 0 -30.5 18t3.5 35l556 757q9 14 27 14h332q14 0 24 -10 t10 -24zM1783 641q0 -193 -125.5 -303t-324.5 -110h-270q-14 0 -24 10t-10 24v756q0 14 10 24t24 10h268q200 0 326 -109t126 -302zM1939 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-44.5 -108t-73.5 -102.5h-51q38 45 66.5 104.5t41.5 112t21 98t9 72.5l1 27q0 8 -0.5 22.5 t-7.5 60t-20 91.5t-41 111.5t-66 124.5h43q41 -47 72 -107t45.5 -111.5t23 -96t10.5 -70.5zM2123 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-45 -108t-74 -102.5h-51q38 45 66.5 104.5t41.5 112t21 98t9 72.5l1 27q0 8 -0.5 22.5t-7.5 60t-19.5 91.5t-40.5 111.5t-66 124.5 h43q41 -47 72 -107t45.5 -111.5t23 -96t10.5 -70.5zM2304 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-44.5 -108t-73.5 -102.5h-51q38 45 66 104.5t41 112t21 98t9 72.5l1 27q0 8 -0.5 22.5t-7.5 60t-19.5 91.5t-40.5 111.5t-66 124.5h43q41 -47 72 -107t45.5 -111.5t23 -96 t9.5 -70.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1408" d="M617 -153q0 11 -13 58t-31 107t-20 69q-1 4 -5 26.5t-8.5 36t-13.5 21.5q-15 14 -51 14q-23 0 -70 -5.5t-71 -5.5q-34 0 -47 11q-6 5 -11 15.5t-7.5 20t-6.5 24t-5 18.5q-37 128 -37 255t37 255q1 4 5 18.5t6.5 24t7.5 20t11 15.5q13 11 47 11q24 0 71 -5.5t70 -5.5 q36 0 51 14q9 8 13.5 21.5t8.5 36t5 26.5q2 9 20 69t31 107t13 58q0 22 -43.5 52.5t-75.5 42.5q-20 8 -45 8q-34 0 -98 -18q-57 -17 -96.5 -40.5t-71 -66t-46 -70t-45.5 -94.5q-6 -12 -9 -19q-49 -107 -68 -216t-19 -244t19 -244t68 -216q56 -122 83 -161q63 -91 179 -127 l6 -2q64 -18 98 -18q25 0 45 8q32 12 75.5 42.5t43.5 52.5zM776 760q-26 0 -45 19t-19 45.5t19 45.5q37 37 37 90q0 52 -37 91q-19 19 -19 45t19 45t45 19t45 -19q75 -75 75 -181t-75 -181q-21 -19 -45 -19zM957 579q-27 0 -45 19q-19 19 -19 45t19 45q112 114 112 272 t-112 272q-19 19 -19 45t19 45t45 19t45 -19q150 -150 150 -362t-150 -362q-18 -19 -45 -19zM1138 398q-27 0 -45 19q-19 19 -19 45t19 45q90 91 138.5 208t48.5 245t-48.5 245t-138.5 208q-19 19 -19 45t19 45t45 19t45 -19q109 -109 167 -249t58 -294t-58 -294t-167 -249 q-18 -19 -45 -19z" />
|
||||
<glyph unicode="" horiz-adv-x="2176" d="M192 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM704 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM704 864q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1472 352 q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1472 864q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 864 q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 1376q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 192q0 -80 -56 -136 t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 1216q0 -80 -56 -136t-136 -56 t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM2176 192q0 -80 -56 -136t-136 -56t-136 56 t-56 136t56 136t136 56t136 -56t56 -136zM1664 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM2176 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136 t56 136t136 56t136 -56t56 -136zM2176 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M128 -192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM320 0q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM365 365l256 -256l-90 -90l-256 256zM704 384q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45z M1411 704q0 -59 -11.5 -108.5t-37.5 -93.5t-44 -67.5t-53 -64.5q-31 -35 -45.5 -54t-33.5 -50t-26.5 -64t-7.5 -74q0 -159 -112.5 -271.5t-271.5 -112.5q-26 0 -45 19t-19 45t19 45t45 19q106 0 181 75t75 181q0 57 11.5 105.5t37 91t43.5 66.5t52 63q40 46 59.5 72 t37.5 74.5t18 103.5q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM896 576q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45 t45 19t45 -19t19 -45zM1184 704q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 93 -65.5 158.5t-158.5 65.5q-92 0 -158 -65.5t-66 -158.5q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 146 103 249t249 103t249 -103t103 -249zM1578 993q10 -25 -1 -49t-36 -34q-9 -4 -23 -4 q-19 0 -35.5 11t-23.5 30q-68 178 -224 295q-21 16 -25 42t12 47q17 21 43 25t47 -12q183 -137 266 -351zM1788 1074q9 -25 -1.5 -49t-35.5 -34q-11 -4 -23 -4q-44 0 -60 41q-92 238 -297 393q-22 16 -25.5 42t12.5 47q16 22 42 25.5t47 -12.5q235 -175 341 -449z" />
|
||||
<glyph unicode="" horiz-adv-x="2304" d="M1032 576q-59 2 -84 55q-17 34 -48 53.5t-68 19.5q-53 0 -90.5 -37.5t-37.5 -90.5q0 -56 36 -89l10 -8q34 -31 82 -31q37 0 68 19.5t48 53.5q25 53 84 55zM1600 704q0 56 -36 89l-10 8q-34 31 -82 31q-37 0 -68 -19.5t-48 -53.5q-25 -53 -84 -55q59 -2 84 -55 q17 -34 48 -53.5t68 -19.5q53 0 90.5 37.5t37.5 90.5zM1174 925q-17 -35 -55 -48t-73 4q-62 31 -134 31q-51 0 -99 -17q3 0 9.5 0.5t9.5 0.5q92 0 170.5 -50t118.5 -133q17 -36 3.5 -73.5t-49.5 -54.5q-18 -9 -39 -9q21 0 39 -9q36 -17 49.5 -54.5t-3.5 -73.5 q-40 -83 -118.5 -133t-170.5 -50h-6q-16 2 -44 4l-290 27l-239 -120q-14 -7 -29 -7q-40 0 -57 35l-160 320q-11 23 -4 47.5t29 37.5l209 119l148 267q17 155 91.5 291.5t195.5 236.5q31 25 70.5 21.5t64.5 -34.5t21.5 -70t-34.5 -65q-70 -59 -117 -128q123 84 267 101 q40 5 71.5 -19t35.5 -64q5 -40 -19 -71.5t-64 -35.5q-84 -10 -159 -55q46 10 99 10q115 0 218 -50q36 -18 49 -55.5t-5 -73.5zM2137 1085l160 -320q11 -23 4 -47.5t-29 -37.5l-209 -119l-148 -267q-17 -155 -91.5 -291.5t-195.5 -236.5q-26 -22 -61 -22q-45 0 -74 35 q-25 31 -21.5 70t34.5 65q70 59 117 128q-123 -84 -267 -101q-4 -1 -12 -1q-36 0 -63.5 24t-31.5 60q-5 40 19 71.5t64 35.5q84 10 159 55q-46 -10 -99 -10q-115 0 -218 50q-36 18 -49 55.5t5 73.5q17 35 55 48t73 -4q62 -31 134 -31q51 0 99 17q-3 0 -9.5 -0.5t-9.5 -0.5 q-92 0 -170.5 50t-118.5 133q-17 36 -3.5 73.5t49.5 54.5q18 9 39 9q-21 0 -39 9q-36 17 -49.5 54.5t3.5 73.5q40 83 118.5 133t170.5 50h6h1q14 -2 42 -4l291 -27l239 120q14 7 29 7q40 0 57 -35z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M1056 704q0 -26 19 -45t45 -19t45 19t19 45q0 146 -103 249t-249 103t-249 -103t-103 -249q0 -26 19 -45t45 -19t45 19t19 45q0 93 66 158.5t158 65.5t158 -65.5t66 -158.5zM835 1280q-117 0 -223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5q0 -26 19 -45t45 -19t45 19 t19 45q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -55 -18 -103.5t-37.5 -74.5t-59.5 -72q-34 -39 -52 -63t-43.5 -66.5t-37 -91t-11.5 -105.5q0 -106 -75 -181t-181 -75q-26 0 -45 -19t-19 -45t19 -45t45 -19q159 0 271.5 112.5t112.5 271.5q0 41 7.5 74 t26.5 64t33.5 50t45.5 54q35 41 53 64.5t44 67.5t37.5 93.5t11.5 108.5q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5zM591 561l226 -226l-579 -579q-12 -12 -29 -12t-29 12l-168 168q-12 12 -12 29t12 29zM1612 1524l168 -168q12 -12 12 -29t-12 -30l-233 -233 l-26 -25l-71 -71q-66 153 -195 258l91 91l207 207q13 12 30 12t29 -12z" />
|
||||
<glyph unicode="" d="M866 1021q0 -27 -13 -94q-11 -50 -31.5 -150t-30.5 -150q-2 -11 -4.5 -12.5t-13.5 -2.5q-20 -2 -31 -2q-58 0 -84 49.5t-26 113.5q0 88 35 174t103 124q28 14 51 14q28 0 36.5 -16.5t8.5 -47.5zM1352 597q0 14 -39 75.5t-52 66.5q-21 8 -34 8q-91 0 -226 -77l-2 2 q3 22 27.5 135t24.5 178q0 233 -242 233q-24 0 -68 -6q-94 -17 -168.5 -89.5t-111.5 -166.5t-37 -189q0 -146 80.5 -225t227.5 -79q25 0 25 -3t-1 -5q-4 -34 -26 -117q-14 -52 -51.5 -101t-82.5 -49q-42 0 -42 47q0 24 10.5 47.5t25 39.5t29.5 28.5t26 20t11 8.5q0 3 -7 10 q-24 22 -58.5 36.5t-65.5 14.5q-35 0 -63.5 -34t-41 -75t-12.5 -75q0 -88 51.5 -142t138.5 -54q82 0 155 53t117.5 126t65.5 153q6 22 15.5 66.5t14.5 66.5q3 12 14 18q118 60 227 60q48 0 127 -18q1 -1 4 -1q5 0 9.5 4.5t4.5 8.5zM1536 1120v-960q0 -119 -84.5 -203.5 t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1535" d="M744 1231q0 24 -2 38.5t-8.5 30t-21 23t-37.5 7.5q-39 0 -78 -23q-105 -58 -159 -190.5t-54 -269.5q0 -44 8.5 -85.5t26.5 -80.5t52.5 -62.5t81.5 -23.5q4 0 18 -0.5t20 0t16 3t15 8.5t7 16q16 77 48 231.5t48 231.5q19 91 19 146zM1498 575q0 -7 -7.5 -13.5t-15.5 -6.5 l-6 1q-22 3 -62 11t-72 12.5t-63 4.5q-167 0 -351 -93q-15 -8 -21 -27q-10 -36 -24.5 -105.5t-22.5 -100.5q-23 -91 -70 -179.5t-112.5 -164.5t-154.5 -123t-185 -47q-135 0 -214.5 83.5t-79.5 219.5q0 53 19.5 117t63 116.5t97.5 52.5q38 0 120 -33.5t83 -61.5 q0 -1 -16.5 -12.5t-39.5 -31t-46 -44.5t-39 -61t-16 -74q0 -33 16.5 -53t48.5 -20q45 0 85 31.5t66.5 78t48 105.5t32.5 107t16 90v9q0 2 -3.5 3.5t-8.5 1.5h-10t-10 -0.5t-6 -0.5q-227 0 -352 122.5t-125 348.5q0 108 34.5 221t96 210t156 167.5t204.5 89.5q52 9 106 9 q374 0 374 -360q0 -98 -38 -273t-43 -211l3 -3q101 57 182.5 88t167.5 31q22 0 53 -13q19 -7 80 -102.5t61 -116.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1664" d="M831 863q32 0 59 -18l222 -148q61 -40 110 -97l146 -170q40 -46 29 -106l-72 -413q-6 -32 -29.5 -53.5t-55.5 -25.5l-527 -56l-352 -32h-9q-39 0 -67.5 28t-28.5 68q0 37 27 64t65 32l260 32h-448q-41 0 -69.5 30t-26.5 71q2 39 32 65t69 26l442 1l-521 64q-41 5 -66 37 t-19 73q6 35 34.5 57.5t65.5 22.5h10l481 -60l-351 94q-38 10 -62 41.5t-18 68.5q6 36 33 58.5t62 22.5q6 0 20 -2l448 -96l217 -37q1 0 3 -0.5t3 -0.5q23 0 30.5 23t-12.5 36l-186 125q-35 23 -42 63.5t18 73.5q27 38 76 38zM761 661l186 -125l-218 37l-5 2l-36 38 l-238 262q-1 1 -2.5 3.5t-2.5 3.5q-24 31 -18.5 70t37.5 64q31 23 68 17.5t64 -33.5l142 -147l-4 -4t-5 -4q-32 -45 -23 -99t55 -85zM1648 1115l15 -266q4 -73 -11 -147l-48 -219q-12 -59 -67 -87l-106 -54q2 62 -39 109l-146 170q-53 61 -117 103l-222 148q-34 23 -76 23 q-51 0 -88 -37l-235 312q-25 33 -18 73.5t41 63.5q33 22 71.5 14t62.5 -40l266 -352l-262 455q-21 35 -10.5 75t47.5 59q35 18 72.5 6t57.5 -46l241 -420l-136 337q-15 35 -4.5 74t44.5 56q37 19 76 6t56 -51l193 -415l101 -196q8 -15 23 -17.5t27 7.5t11 26l-12 224 q-2 41 26 71t69 31q39 0 67 -28.5t30 -67.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M335 180q-2 0 -6 2q-86 57 -168.5 145t-139.5 180q-21 30 -21 69q0 9 2 19t4 18t7 18t8.5 16t10.5 17t10 15t12 15.5t11 14.5q184 251 452 365q-110 198 -110 211q0 19 17 29q116 64 128 64q18 0 28 -16l124 -229q92 19 192 19q266 0 497.5 -137.5t378.5 -369.5 q20 -31 20 -69t-20 -69q-91 -142 -218.5 -253.5t-278.5 -175.5q110 -198 110 -211q0 -20 -17 -29q-116 -64 -127 -64q-19 0 -29 16l-124 229l-64 119l-444 820l7 7q-58 -24 -99 -47q3 -5 127 -234t243 -449t119 -223q0 -7 -9 -9q-13 -3 -72 -3q-57 0 -60 7l-456 841 q-39 -28 -82 -68q24 -43 214 -393.5t190 -354.5q0 -10 -11 -10q-14 0 -82.5 22t-72.5 28l-106 197l-224 413q-44 -53 -78 -106q2 -3 18 -25t23 -34l176 -327q0 -10 -10 -10zM1165 282l49 -91q273 111 450 385q-180 277 -459 389q67 -64 103 -148.5t36 -176.5 q0 -106 -47 -200.5t-132 -157.5zM848 896q0 -20 14 -34t34 -14q86 0 147 -61t61 -147q0 -20 14 -34t34 -14t34 14t14 34q0 126 -89 215t-215 89q-20 0 -34 -14t-14 -34zM1214 961l-9 4l7 -7z" />
|
||||
<glyph unicode="" horiz-adv-x="1280" d="M1050 430q0 -215 -147 -374q-148 -161 -378 -161q-232 0 -378 161q-147 159 -147 374q0 147 68 270.5t189 196.5t268 73q96 0 182 -31q-32 -62 -39 -126q-66 28 -143 28q-167 0 -280.5 -123t-113.5 -291q0 -170 112.5 -288.5t281.5 -118.5t281 118.5t112 288.5 q0 89 -32 166q66 13 123 49q41 -98 41 -212zM846 619q0 -192 -79.5 -345t-238.5 -253l-14 -1q-29 0 -62 5q83 32 146.5 102.5t99.5 154.5t58.5 189t30 192.5t7.5 178.5q0 69 -3 103q55 -160 55 -326zM791 947v-2q-73 214 -206 440q88 -59 142.5 -186.5t63.5 -251.5z M1035 744q-83 0 -160 75q218 120 290 247q19 37 21 56q-42 -94 -139.5 -166.5t-204.5 -97.5q-35 54 -35 113q0 37 17 79t43 68q46 44 157 74q59 16 106 58.5t74 100.5q74 -105 74 -253q0 -109 -24 -170q-32 -77 -88.5 -130.5t-130.5 -53.5z" />
|
||||
<glyph unicode="" d="M1050 495q0 78 -28 147q-41 -25 -85 -34q22 -50 22 -114q0 -117 -77 -198.5t-193 -81.5t-193.5 81.5t-77.5 198.5q0 115 78 199.5t193 84.5q53 0 98 -19q4 43 27 87q-60 21 -125 21q-154 0 -257.5 -108.5t-103.5 -263.5t103.5 -261t257.5 -106t257.5 106.5t103.5 260.5z M872 850q2 -24 2 -71q0 -63 -5 -123t-20.5 -132.5t-40.5 -130t-68.5 -106t-100.5 -70.5q21 -3 42 -3h10q219 139 219 411q0 116 -38 225zM872 850q-4 80 -44 171.5t-98 130.5q92 -156 142 -302zM1207 955q0 102 -51 174q-41 -86 -124 -109q-69 -19 -109 -53.5t-40 -99.5 q0 -40 24 -77q74 17 140.5 67t95.5 115q-4 -52 -74.5 -111.5t-138.5 -97.5q52 -52 110 -52q51 0 90 37t60 90q17 43 17 117zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 t84.5 -203.5z" />
|
||||
<glyph unicode="" d="M1279 388q0 22 -22 27q-67 15 -118 59t-80 108q-7 19 -7 25q0 15 19.5 26t43 17t43 20.5t19.5 36.5q0 19 -18.5 31.5t-38.5 12.5q-12 0 -32 -8t-31 -8q-4 0 -12 2q5 95 5 114q0 79 -17 114q-36 78 -103 121.5t-152 43.5q-199 0 -275 -165q-17 -35 -17 -114q0 -19 5 -114 q-4 -2 -14 -2q-12 0 -32 7.5t-30 7.5q-21 0 -38.5 -12t-17.5 -32q0 -21 19.5 -35.5t43 -20.5t43 -17t19.5 -26q0 -6 -7 -25q-64 -138 -198 -167q-22 -5 -22 -27q0 -46 137 -68q2 -5 6 -26t11.5 -30.5t23.5 -9.5q12 0 37.5 4.5t39.5 4.5q35 0 67 -15t54 -32.5t57.5 -32.5 t76.5 -15q43 0 79 15t57.5 32.5t53.5 32.5t67 15q14 0 39.5 -4t38.5 -4q16 0 23 10t11 30t6 25q137 22 137 68zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 t103 -385.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1664" d="M848 1408q134 1 240.5 -68.5t163.5 -192.5q27 -58 27 -179q0 -47 -9 -191q14 -7 28 -7q18 0 51 13.5t51 13.5q29 0 56 -18t27 -46q0 -32 -31.5 -54t-69 -31.5t-69 -29t-31.5 -47.5q0 -15 12 -43q37 -82 102.5 -150t144.5 -101q28 -12 80 -23q28 -6 28 -35 q0 -70 -219 -103q-7 -11 -11 -39t-14 -46.5t-33 -18.5q-20 0 -62 6.5t-64 6.5q-37 0 -62 -5q-32 -5 -63 -22.5t-58 -38t-58 -40.5t-76 -33.5t-99 -13.5q-52 0 -96.5 13.5t-75 33.5t-57.5 40.5t-58 38t-62 22.5q-26 5 -63 5q-24 0 -65.5 -7.5t-58.5 -7.5q-25 0 -35 18.5 t-14 47.5t-11 40q-219 33 -219 103q0 29 28 35q52 11 80 23q78 32 144.5 101t102.5 150q12 28 12 43q0 28 -31.5 47.5t-69.5 29.5t-69.5 31.5t-31.5 52.5q0 27 26 45.5t55 18.5q15 0 48 -13t53 -13q18 0 32 7q-9 142 -9 190q0 122 27 180q64 137 172 198t264 63z" />
|
||||
<glyph unicode="" d="M1280 388q0 22 -22 27q-67 14 -118 58t-80 109q-7 14 -7 25q0 15 19.5 26t42.5 17t42.5 20.5t19.5 36.5q0 19 -18.5 31.5t-38.5 12.5q-11 0 -31 -8t-32 -8q-4 0 -12 2q5 63 5 115q0 78 -17 114q-36 78 -102.5 121.5t-152.5 43.5q-198 0 -275 -165q-18 -38 -18 -115 q0 -38 6 -114q-10 -2 -15 -2q-11 0 -31.5 8t-30.5 8q-20 0 -37.5 -12.5t-17.5 -32.5q0 -21 19.5 -35.5t42.5 -20.5t42.5 -17t19.5 -26q0 -11 -7 -25q-64 -138 -198 -167q-22 -5 -22 -27q0 -47 138 -69q2 -5 6 -26t11 -30.5t23 -9.5q13 0 38.5 5t38.5 5q35 0 67.5 -15 t54.5 -32.5t57.5 -32.5t76.5 -15q43 0 79 15t57.5 32.5t54 32.5t67.5 15q13 0 39 -4.5t39 -4.5q15 0 22.5 9.5t11.5 31t5 24.5q138 22 138 69zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960 q119 0 203.5 -84.5t84.5 -203.5z" />
|
||||
<glyph unicode="" horiz-adv-x="2304" d="M2304 1536q-69 -46 -125 -92t-89 -81t-59.5 -71.5t-37.5 -57.5t-22 -44.5t-14 -29.5q-10 -18 -35.5 -136.5t-48.5 -164.5q-15 -29 -50 -60.5t-67.5 -50.5t-72.5 -41t-48 -28q-47 -31 -151 -231q-341 14 -630 -158q-92 -53 -303 -179q47 16 86 31t55 22l15 7 q71 27 163 64.5t133.5 53.5t108 34.5t142.5 31.5q186 31 465 -7q1 0 10 -3q11 -6 14 -17t-3 -22l-194 -345q-15 -29 -47 -22q-128 24 -354 24q-146 0 -402 -44.5t-392 -46.5q-82 -1 -149 13t-107 37t-61 40t-33 34l-1 1v2q0 6 6 6q138 0 371 55q192 366 374.5 524t383.5 158 q5 0 14.5 -0.5t38 -5t55 -12t61.5 -24.5t63 -39.5t54 -59t40 -82.5l102 177q2 4 21 42.5t44.5 86.5t61 109.5t84 133.5t100.5 137q66 82 128 141.5t121.5 96.5t92.5 53.5t88 39.5z" />
|
||||
<glyph unicode="" d="M1322 640q0 -45 -5 -76l-236 14l224 -78q-19 -73 -58 -141l-214 103l177 -158q-44 -61 -107 -108l-157 178l103 -215q-61 -37 -140 -59l-79 228l14 -240q-38 -6 -76 -6t-76 6l14 238l-78 -226q-74 19 -140 59l103 215l-157 -178q-59 43 -108 108l178 158l-214 -104 q-39 69 -58 141l224 79l-237 -14q-5 42 -5 76q0 35 5 77l238 -14l-225 79q19 73 58 140l214 -104l-177 159q46 61 107 108l158 -178l-103 215q67 39 140 58l77 -224l-13 236q36 6 75 6q38 0 76 -6l-14 -237l78 225q74 -19 140 -59l-103 -214l158 178q61 -47 107 -108 l-177 -159l213 104q37 -62 58 -141l-224 -78l237 14q5 -31 5 -77zM1352 640q0 160 -78.5 295.5t-213 214t-292.5 78.5q-119 0 -227 -46.5t-186.5 -125t-124.5 -187.5t-46 -229q0 -119 46 -228t124.5 -187.5t186.5 -125t227 -46.5q158 0 292.5 78.5t213 214t78.5 294.5z M1425 1023v-766l-657 -383l-657 383v766l657 383zM768 -183l708 412v823l-708 411l-708 -411v-823zM1536 1088v-896l-768 -448l-768 448v896l768 448z" />
|
||||
<glyph unicode="" horiz-adv-x="1664" d="M339 1318h691l-26 -72h-665q-110 0 -188.5 -79t-78.5 -189v-771q0 -95 60.5 -169.5t153.5 -93.5q23 -5 98 -5v-72h-45q-140 0 -239.5 100t-99.5 240v771q0 140 99.5 240t239.5 100zM1190 1536h247l-482 -1294q-23 -61 -40.5 -103.5t-45 -98t-54 -93.5t-64.5 -78.5 t-79.5 -65t-95.5 -41t-116 -18.5v195q163 26 220 182q20 52 20 105q0 54 -20 106l-285 733h228l187 -585zM1664 978v-1111h-795q37 55 45 73h678v1038q0 85 -49.5 155t-129.5 99l25 67q101 -34 163.5 -123.5t62.5 -197.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M852 1227q0 -29 -17 -52.5t-45 -23.5t-45 23.5t-17 52.5t17 52.5t45 23.5t45 -23.5t17 -52.5zM688 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50 -21.5t-20 -51.5v-114q0 -30 20.5 -52t49.5 -22q30 0 50.5 22t20.5 52zM860 -149v114q0 30 -20 51.5t-50 21.5t-50.5 -21.5 t-20.5 -51.5v-114q0 -30 20.5 -52t50.5 -22q29 0 49.5 22t20.5 52zM1034 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50.5 -21.5t-20.5 -51.5v-114q0 -30 20.5 -52t50.5 -22t50.5 22t20.5 52zM1208 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50.5 -21.5t-20.5 -51.5v-114 q0 -30 20.5 -52t50.5 -22t50.5 22t20.5 52zM1476 535q-84 -160 -232 -259.5t-323 -99.5q-123 0 -229.5 51.5t-178.5 137t-113 197.5t-41 232q0 88 21 174q-104 -175 -104 -390q0 -162 65 -312t185 -251q30 57 91 57q56 0 86 -50q32 50 87 50q56 0 86 -50q32 50 87 50t87 -50 q30 50 86 50q28 0 52.5 -15.5t37.5 -40.5q112 94 177 231.5t73 287.5zM1326 564q0 75 -72 75q-17 0 -47 -6q-95 -19 -149 -19q-226 0 -226 243q0 86 30 204q-83 -127 -83 -275q0 -150 89 -260.5t235 -110.5q111 0 210 70q13 48 13 79zM884 1223q0 50 -32 89.5t-81 39.5 t-81 -39.5t-32 -89.5q0 -51 31.5 -90.5t81.5 -39.5t81.5 39.5t31.5 90.5zM1513 884q0 96 -37.5 179t-113 137t-173.5 54q-77 0 -149 -35t-127 -94q-48 -159 -48 -268q0 -104 45.5 -157t147.5 -53q53 0 142 19q36 6 53 6q51 0 77.5 -28t26.5 -80q0 -26 -4 -46 q75 68 117.5 165.5t42.5 200.5zM1792 667q0 -111 -33.5 -249.5t-93.5 -204.5q-58 -64 -195 -142.5t-228 -104.5l-4 -1v-114q0 -43 -29.5 -75t-72.5 -32q-56 0 -86 50q-32 -50 -87 -50t-87 50q-30 -50 -86 -50q-55 0 -87 50q-30 -50 -86 -50q-47 0 -75 33.5t-28 81.5 q-90 -68 -198 -68q-118 0 -211 80q54 1 106 20q-113 31 -182 127q32 -7 71 -7q89 0 164 46q-192 192 -240 306q-24 56 -24 160q0 57 9 125.5t31.5 146.5t55 141t86.5 105t120 42q59 0 81 -52q19 29 42 54q2 3 12 13t13 16q10 15 23 38t25 42t28 39q87 111 211.5 177 t260.5 66q35 0 62 -4q59 64 146 64q83 0 140 -57q5 -5 5 -12q0 -5 -6 -13.5t-12.5 -16t-16 -17l-10.5 -10.5q17 -6 36 -18t19 -24q0 -6 -16 -25q157 -138 197 -378q25 30 60 30q45 0 100 -49q90 -80 90 -279z" />
|
||||
<glyph unicode="" d="M917 631q0 33 -6 64h-362v-132h217q-12 -76 -74.5 -120.5t-142.5 -44.5q-99 0 -169 71.5t-70 170.5t70 170.5t169 71.5q93 0 153 -59l104 101q-108 100 -257 100q-160 0 -272 -112.5t-112 -271.5t112 -271.5t272 -112.5q165 0 266.5 105t101.5 270zM1262 585h109v110 h-109v110h-110v-110h-110v-110h110v-110h110v110zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
|
||||
<glyph unicode="" d="M1536 1024v-839q0 -48 -49 -62q-174 -52 -338 -52q-73 0 -215.5 29.5t-227.5 29.5q-164 0 -370 -48v-338h-160v1368q-63 25 -101 81t-38 124q0 91 64 155t155 64t155 -64t64 -155q0 -68 -38 -124t-101 -81v-68q190 44 343 44q99 0 198 -15q14 -2 111.5 -22.5t149.5 -20.5 q77 0 165 18q11 2 80 21t89 19q26 0 45 -19t19 -45z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
</font>
|
||||
</defs></svg>
|
||||
|
Before Width: | Height: | Size: 357 KiB After Width: | Height: | Size: 382 KiB |
Binary file not shown.
BIN
public/assets/font-awesome-4.6.3/fonts/fontawesome-webfont.woff
Normal file
BIN
public/assets/font-awesome-4.6.3/fonts/fontawesome-webfont.woff
Normal file
Binary file not shown.
BIN
public/assets/font-awesome-4.6.3/fonts/fontawesome-webfont.woff2
Normal file
BIN
public/assets/font-awesome-4.6.3/fonts/fontawesome-webfont.woff2
Normal file
Binary file not shown.
226
public/assets/octicons-3.5.0/octicons.css
vendored
226
public/assets/octicons-3.5.0/octicons.css
vendored
@@ -1,226 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'octicons';
|
||||
src: url('octicons.eot?#iefix') format('embedded-opentype'),
|
||||
url('octicons.woff') format('woff'),
|
||||
url('octicons.ttf') format('truetype'),
|
||||
url('octicons.svg#octicons') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
.octicon is optimized for 16px.
|
||||
.mega-octicon is optimized for 32px but can be used larger.
|
||||
|
||||
*/
|
||||
.octicon, .mega-octicon {
|
||||
font: normal normal normal 16px/1 octicons;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.mega-octicon { font-size: 32px; }
|
||||
|
||||
.octicon-alert:before { content: '\f02d'} /* */
|
||||
.octicon-arrow-down:before { content: '\f03f'} /* */
|
||||
.octicon-arrow-left:before { content: '\f040'} /* */
|
||||
.octicon-arrow-right:before { content: '\f03e'} /* */
|
||||
.octicon-arrow-small-down:before { content: '\f0a0'} /* */
|
||||
.octicon-arrow-small-left:before { content: '\f0a1'} /* */
|
||||
.octicon-arrow-small-right:before { content: '\f071'} /* */
|
||||
.octicon-arrow-small-up:before { content: '\f09f'} /* */
|
||||
.octicon-arrow-up:before { content: '\f03d'} /* */
|
||||
.octicon-microscope:before,
|
||||
.octicon-beaker:before { content: '\f0dd'} /* */
|
||||
.octicon-bell:before { content: '\f0de'} /* */
|
||||
.octicon-bold:before { content: '\f0e2'} /* */
|
||||
.octicon-book:before { content: '\f007'} /* */
|
||||
.octicon-bookmark:before { content: '\f07b'} /* */
|
||||
.octicon-briefcase:before { content: '\f0d3'} /* */
|
||||
.octicon-broadcast:before { content: '\f048'} /* */
|
||||
.octicon-browser:before { content: '\f0c5'} /* */
|
||||
.octicon-bug:before { content: '\f091'} /* */
|
||||
.octicon-calendar:before { content: '\f068'} /* */
|
||||
.octicon-check:before { content: '\f03a'} /* */
|
||||
.octicon-checklist:before { content: '\f076'} /* */
|
||||
.octicon-chevron-down:before { content: '\f0a3'} /* */
|
||||
.octicon-chevron-left:before { content: '\f0a4'} /* */
|
||||
.octicon-chevron-right:before { content: '\f078'} /* */
|
||||
.octicon-chevron-up:before { content: '\f0a2'} /* */
|
||||
.octicon-circle-slash:before { content: '\f084'} /* */
|
||||
.octicon-circuit-board:before { content: '\f0d6'} /* */
|
||||
.octicon-clippy:before { content: '\f035'} /* */
|
||||
.octicon-clock:before { content: '\f046'} /* */
|
||||
.octicon-cloud-download:before { content: '\f00b'} /* */
|
||||
.octicon-cloud-upload:before { content: '\f00c'} /* */
|
||||
.octicon-code:before { content: '\f05f'} /* */
|
||||
.octicon-comment-add:before,
|
||||
.octicon-comment:before { content: '\f02b'} /* */
|
||||
.octicon-comment-discussion:before { content: '\f04f'} /* */
|
||||
.octicon-credit-card:before { content: '\f045'} /* */
|
||||
.octicon-dash:before { content: '\f0ca'} /* */
|
||||
.octicon-dashboard:before { content: '\f07d'} /* */
|
||||
.octicon-database:before { content: '\f096'} /* */
|
||||
.octicon-clone:before,
|
||||
.octicon-desktop-download:before { content: '\f0dc'} /* */
|
||||
.octicon-device-camera:before { content: '\f056'} /* */
|
||||
.octicon-device-camera-video:before { content: '\f057'} /* */
|
||||
.octicon-device-desktop:before { content: '\f27c'} /* */
|
||||
.octicon-device-mobile:before { content: '\f038'} /* */
|
||||
.octicon-diff:before { content: '\f04d'} /* */
|
||||
.octicon-diff-added:before { content: '\f06b'} /* */
|
||||
.octicon-diff-ignored:before { content: '\f099'} /* */
|
||||
.octicon-diff-modified:before { content: '\f06d'} /* */
|
||||
.octicon-diff-removed:before { content: '\f06c'} /* */
|
||||
.octicon-diff-renamed:before { content: '\f06e'} /* */
|
||||
.octicon-ellipsis:before { content: '\f09a'} /* */
|
||||
.octicon-eye-unwatch:before,
|
||||
.octicon-eye-watch:before,
|
||||
.octicon-eye:before { content: '\f04e'} /* */
|
||||
.octicon-file-binary:before { content: '\f094'} /* */
|
||||
.octicon-file-code:before { content: '\f010'} /* */
|
||||
.octicon-file-directory:before { content: '\f016'} /* */
|
||||
.octicon-file-media:before { content: '\f012'} /* */
|
||||
.octicon-file-pdf:before { content: '\f014'} /* */
|
||||
.octicon-file-submodule:before { content: '\f017'} /* */
|
||||
.octicon-file-symlink-directory:before { content: '\f0b1'} /* */
|
||||
.octicon-file-symlink-file:before { content: '\f0b0'} /* */
|
||||
.octicon-file-text:before { content: '\f011'} /* */
|
||||
.octicon-file-zip:before { content: '\f013'} /* */
|
||||
.octicon-flame:before { content: '\f0d2'} /* */
|
||||
.octicon-fold:before { content: '\f0cc'} /* */
|
||||
.octicon-gear:before { content: '\f02f'} /* */
|
||||
.octicon-gift:before { content: '\f042'} /* */
|
||||
.octicon-gist:before { content: '\f00e'} /* */
|
||||
.octicon-gist-secret:before { content: '\f08c'} /* */
|
||||
.octicon-git-branch-create:before,
|
||||
.octicon-git-branch-delete:before,
|
||||
.octicon-git-branch:before { content: '\f020'} /* */
|
||||
.octicon-git-commit:before { content: '\f01f'} /* */
|
||||
.octicon-git-compare:before { content: '\f0ac'} /* */
|
||||
.octicon-git-merge:before { content: '\f023'} /* */
|
||||
.octicon-git-pull-request-abandoned:before,
|
||||
.octicon-git-pull-request:before { content: '\f009'} /* */
|
||||
.octicon-globe:before { content: '\f0b6'} /* */
|
||||
.octicon-graph:before { content: '\f043'} /* */
|
||||
.octicon-heart:before { content: '\2665'} /* ♥ */
|
||||
.octicon-history:before { content: '\f07e'} /* */
|
||||
.octicon-home:before { content: '\f08d'} /* */
|
||||
.octicon-horizontal-rule:before { content: '\f070'} /* */
|
||||
.octicon-hubot:before { content: '\f09d'} /* */
|
||||
.octicon-inbox:before { content: '\f0cf'} /* */
|
||||
.octicon-info:before { content: '\f059'} /* */
|
||||
.octicon-issue-closed:before { content: '\f028'} /* */
|
||||
.octicon-issue-opened:before { content: '\f026'} /* */
|
||||
.octicon-issue-reopened:before { content: '\f027'} /* */
|
||||
.octicon-italic:before { content: '\f0e4'} /* */
|
||||
.octicon-jersey:before { content: '\f019'} /* */
|
||||
.octicon-key:before { content: '\f049'} /* */
|
||||
.octicon-keyboard:before { content: '\f00d'} /* */
|
||||
.octicon-law:before { content: '\f0d8'} /* */
|
||||
.octicon-light-bulb:before { content: '\f000'} /* */
|
||||
.octicon-link:before { content: '\f05c'} /* */
|
||||
.octicon-link-external:before { content: '\f07f'} /* */
|
||||
.octicon-list-ordered:before { content: '\f062'} /* */
|
||||
.octicon-list-unordered:before { content: '\f061'} /* */
|
||||
.octicon-location:before { content: '\f060'} /* */
|
||||
.octicon-gist-private:before,
|
||||
.octicon-mirror-private:before,
|
||||
.octicon-git-fork-private:before,
|
||||
.octicon-lock:before { content: '\f06a'} /* */
|
||||
.octicon-logo-gist:before { content: '\f0ad'} /* */
|
||||
.octicon-logo-github:before { content: '\f092'} /* */
|
||||
.octicon-mail:before { content: '\f03b'} /* */
|
||||
.octicon-mail-read:before { content: '\f03c'} /* */
|
||||
.octicon-mail-reply:before { content: '\f051'} /* */
|
||||
.octicon-mark-github:before { content: '\f00a'} /* */
|
||||
.octicon-markdown:before { content: '\f0c9'} /* */
|
||||
.octicon-megaphone:before { content: '\f077'} /* */
|
||||
.octicon-mention:before { content: '\f0be'} /* */
|
||||
.octicon-milestone:before { content: '\f075'} /* */
|
||||
.octicon-mirror-public:before,
|
||||
.octicon-mirror:before { content: '\f024'} /* */
|
||||
.octicon-mortar-board:before { content: '\f0d7'} /* */
|
||||
.octicon-mute:before { content: '\f080'} /* */
|
||||
.octicon-no-newline:before { content: '\f09c'} /* */
|
||||
.octicon-octoface:before { content: '\f008'} /* */
|
||||
.octicon-organization:before { content: '\f037'} /* */
|
||||
.octicon-package:before { content: '\f0c4'} /* */
|
||||
.octicon-paintcan:before { content: '\f0d1'} /* */
|
||||
.octicon-pencil:before { content: '\f058'} /* */
|
||||
.octicon-person-add:before,
|
||||
.octicon-person-follow:before,
|
||||
.octicon-person:before { content: '\f018'} /* */
|
||||
.octicon-pin:before { content: '\f041'} /* */
|
||||
.octicon-plug:before { content: '\f0d4'} /* */
|
||||
.octicon-repo-create:before,
|
||||
.octicon-gist-new:before,
|
||||
.octicon-file-directory-create:before,
|
||||
.octicon-file-add:before,
|
||||
.octicon-plus:before { content: '\f05d'} /* */
|
||||
.octicon-primitive-dot:before { content: '\f052'} /* */
|
||||
.octicon-primitive-square:before { content: '\f053'} /* */
|
||||
.octicon-pulse:before { content: '\f085'} /* */
|
||||
.octicon-question:before { content: '\f02c'} /* */
|
||||
.octicon-quote:before { content: '\f063'} /* */
|
||||
.octicon-radio-tower:before { content: '\f030'} /* */
|
||||
.octicon-repo-delete:before,
|
||||
.octicon-repo:before { content: '\f001'} /* */
|
||||
.octicon-repo-clone:before { content: '\f04c'} /* */
|
||||
.octicon-repo-force-push:before { content: '\f04a'} /* */
|
||||
.octicon-gist-fork:before,
|
||||
.octicon-repo-forked:before { content: '\f002'} /* */
|
||||
.octicon-repo-pull:before { content: '\f006'} /* */
|
||||
.octicon-repo-push:before { content: '\f005'} /* */
|
||||
.octicon-rocket:before { content: '\f033'} /* */
|
||||
.octicon-rss:before { content: '\f034'} /* */
|
||||
.octicon-ruby:before { content: '\f047'} /* */
|
||||
.octicon-search-save:before,
|
||||
.octicon-search:before { content: '\f02e'} /* */
|
||||
.octicon-server:before { content: '\f097'} /* */
|
||||
.octicon-settings:before { content: '\f07c'} /* */
|
||||
.octicon-shield:before { content: '\f0e1'} /* */
|
||||
.octicon-log-in:before,
|
||||
.octicon-sign-in:before { content: '\f036'} /* */
|
||||
.octicon-log-out:before,
|
||||
.octicon-sign-out:before { content: '\f032'} /* */
|
||||
.octicon-smiley:before { content: '\f0e7'} /* */
|
||||
.octicon-squirrel:before { content: '\f0b2'} /* */
|
||||
.octicon-star-add:before,
|
||||
.octicon-star-delete:before,
|
||||
.octicon-star:before { content: '\f02a'} /* */
|
||||
.octicon-stop:before { content: '\f08f'} /* */
|
||||
.octicon-repo-sync:before,
|
||||
.octicon-sync:before { content: '\f087'} /* */
|
||||
.octicon-tag-remove:before,
|
||||
.octicon-tag-add:before,
|
||||
.octicon-tag:before { content: '\f015'} /* */
|
||||
.octicon-tasklist:before { content: '\f0e5'} /* */
|
||||
.octicon-telescope:before { content: '\f088'} /* */
|
||||
.octicon-terminal:before { content: '\f0c8'} /* */
|
||||
.octicon-text-size:before { content: '\f0e3'} /* */
|
||||
.octicon-three-bars:before { content: '\f05e'} /* */
|
||||
.octicon-thumbsdown:before { content: '\f0db'} /* */
|
||||
.octicon-thumbsup:before { content: '\f0da'} /* */
|
||||
.octicon-tools:before { content: '\f031'} /* */
|
||||
.octicon-trashcan:before { content: '\f0d0'} /* */
|
||||
.octicon-triangle-down:before { content: '\f05b'} /* */
|
||||
.octicon-triangle-left:before { content: '\f044'} /* */
|
||||
.octicon-triangle-right:before { content: '\f05a'} /* */
|
||||
.octicon-triangle-up:before { content: '\f0aa'} /* */
|
||||
.octicon-unfold:before { content: '\f039'} /* */
|
||||
.octicon-unmute:before { content: '\f0ba'} /* */
|
||||
.octicon-unverified:before { content: '\f0e8'} /* */
|
||||
.octicon-verified:before { content: '\f0e6'} /* */
|
||||
.octicon-versions:before { content: '\f064'} /* */
|
||||
.octicon-watch:before { content: '\f0e0'} /* */
|
||||
.octicon-remove-close:before,
|
||||
.octicon-x:before { content: '\f081'} /* */
|
||||
.octicon-zap:before { content: '\26A1'} /* ⚡ */
|
||||
Binary file not shown.
@@ -1,188 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>
|
||||
(c) 2012-2016 GitHub
|
||||
|
||||
When using the GitHub logos, be sure to follow the GitHub logo guidelines (https://github.com/logos)
|
||||
|
||||
Font License: SIL OFL 1.1 (http://scripts.sil.org/OFL)
|
||||
Applies to all font files
|
||||
|
||||
Code License: MIT (http://choosealicense.com/licenses/mit/)
|
||||
Applies to all other files
|
||||
</metadata>
|
||||
<defs>
|
||||
<font id="octicons" horiz-adv-x="1024" >
|
||||
<font-face font-family="octicons" font-weight="400" font-stretch="normal" units-per-em="1024" ascent="832" descent="-192" />
|
||||
<missing-glyph d="M512 832C229.25 832 0 602.75 0 320c0-226.25 146.688-418.125 350.156-485.812 25.594-4.688 34.938 11.125 34.938 24.625 0 12.188-0.469 52.562-0.719 95.312C242-76.81200000000001 211.906 14.5 211.906 14.5c-23.312 59.125-56.844 74.875-56.844 74.875-46.531 31.75 3.53 31.125 3.53 31.125 51.406-3.562 78.47-52.75 78.47-52.75 45.688-78.25 119.875-55.625 149-42.5 4.654 33 17.904 55.625 32.5 68.375C304.906 106.56200000000001 185.344 150.5 185.344 346.688c0 55.938 19.969 101.562 52.656 137.406-5.219 13-22.844 65.094 5.062 135.562 0 0 42.938 13.75 140.812-52.5 40.812 11.406 84.594 17.031 128.125 17.219 43.5-0.188 87.312-5.875 128.188-17.281 97.688 66.312 140.688 52.5 140.688 52.5 28-70.531 10.375-122.562 5.125-135.5 32.812-35.844 52.625-81.469 52.625-137.406 0-196.688-119.75-240-233.812-252.688 18.438-15.875 34.75-47 34.75-94.75 0-68.438-0.688-123.625-0.688-140.5 0-13.625 9.312-29.562 35.25-24.562C877.438-98 1024 93.875 1024 320 1024 602.75 794.75 832 512 832z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="alert" unicode="" d="M1005.854 31.753000000000043l-438.286 767C556.173 818.694 534.967 831 512 831s-44.173-12.306-55.567-32.247l-438.286-767c-11.319-19.809-11.238-44.144 0.213-63.876C29.811-51.85500000000002 50.899-64 73.714-64h876.572c22.814 0 43.903 12.145 55.354 31.877S1017.173 11.94399999999996 1005.854 31.753000000000043zM576 64H448V192h128V64zM576 256H448V512h128V256z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="arrow-down" unicode="" d="M448 384V640H192v-256H0l320-384 320 384H448z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="arrow-left" unicode="" d="M384 448V640L0 320l384-320V192h256V448H384z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="arrow-right" unicode="" d="M640 320L256 640v-192H0v-256h256v-192L640 320z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="arrow-small-down" unicode="" d="M256 384V512H128v-128H0l192-256 192 256H256z" horiz-adv-x="384" />
|
||||
<glyph glyph-name="arrow-small-left" unicode="" d="M256 384V512L0 320l256-192V256h128V384H256z" horiz-adv-x="384" />
|
||||
<glyph glyph-name="arrow-small-right" unicode="" d="M384 320L128 512v-128H0v-128h128v-128L384 320z" horiz-adv-x="384" />
|
||||
<glyph glyph-name="arrow-small-up" unicode="" d="M192 512L0 256h128v-128h128V256h128L192 512z" horiz-adv-x="384" />
|
||||
<glyph glyph-name="arrow-up" unicode="" d="M320 640L0 256h192v-256h256V256h192L320 640z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="beaker" unicode="" d="M920-102L704 384V640h64v64H192v-64h64v-256L40-102c-19-42 12-90 58-90h764c46 0 77 48 58 90zM240 192l80 192V640h320v-256l80-192H240z m272 128h64v-64h-64v64z m-64 64h-64v64h64v-64z m0 192h64v-64h-64v64z m0 192h-64V832h64v-64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="bell" unicode="" d="M896 64v-64H0v64l47 37c49 49 52 163 76 283 49 241 261 320 261 320 0 35 29 64 64 64s64-29 64-64c0 0 217-79 266-320 24-120 27-234 76-283l42-37z m-448-256c71 0 128 57 128 128H320c0-71 57-128 128-128z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="bold" unicode="" d="M0 704h245c159 0 275-48 275-189 0-73-40-143-107-167v-4c85-19 147-79 147-183 0-153-126-225-295-225H0V704z m234-317c107 0 152 42 152 108 0 75-50 103-150 103H136v-211h98z m17-345c113 0 176 41 176 127 0 81-61 116-176 116H136v-243h115z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="book" unicode="" d="M128 512h256v-64H128v64z m0-192h256v64H128v-64z m0-128h256v64H128v-64z m704 320H576v-64h256v64z m0-128H576v-64h256v64z m0-128H576v-64h256v64z m128 384v-576c0-35-29-64-64-64H544l-64-64-64 64H64c-35 0-64 29-64 64V640c0 35 29 64 64 64h352l64-64 64 64h352c35 0 64-29 64-64z m-512-32l-32 32H64v-576h384V608z m448 32H544l-32-32v-544h384V640z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="bookmark" unicode="" d="M576 832H64C17 832 0 815 0 768v-960l320 198 320-198V768c0 47-17 64-64 64z m-50-272l-119-87 46-138c4-14-1-18-13-11l-120 86-120-86c-12-7-16-3-13 11l46 138-119 87c-11 10-9 15 6 15l147 2 45 138h16l45-138 147-2c15 0 17-5 6-15z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="briefcase" unicode="" d="M576 576v64c0 35-29 64-64 64H384c-35 0-64-29-64-64v-64H64c-35 0-64-29-64-64v-512c0-35 29-64 64-64h768c35 0 64 29 64 64V512c0 35-29 64-64 64H576z m-192 64h128v-64H384v64z m448-384H512v-64H384v64H64V512h64v-192h640V512h64v-256z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="broadcast" unicode="" d="M576 256h-64c35 0 64 29 64 64v64c0 35-29 64-64 64h-64c-35 0-64-29-64-64v-64c0-35 29-64 64-64h-64c-35 0-64-29-64-64v-128h64v-192c0-35 29-64 64-64h64c35 0 64 29 64 64V64h64V192c0 35-29 64-64 64zM448 384h64v-64h-64v64z m128-256h-64v-256h-64V128h-64v64h192v-64z m134 224c0 127-103 230-230 230S250 479 250 352c0-18 2-35 6-52v-127c-39 49-64 111-64 179 0 159 129 288 288 288s288-129 288-288c0-68-25-130-64-179V300c4 17 6 34 6 52z m250 0c0-184-104-344-256-424v67c119 74 198 206 198 357 0 233-189 422-422 422S58 585 58 352c0-151 79-283 198-357v-67C104 8 0 168 0 352 0 617 215 832 480 832s480-215 480-480z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="browser" unicode="" d="M320 640h64v-64h-64V640zM192 640h64v-64h-64V640zM64 640h64v-64H64V640zM832 0H64V512h768V0zM832 576H448v64h384V576zM896 640c0 35.35-28.65 64-64 64H64c-35.35 0-64-28.65-64-64v-640c0-35.35 28.65-64 64-64h768c35.35 0 64 28.65 64 64V640z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="bug" unicode="" d="M704 192h192v64H704v64l203 66-22 60-181-62v64c0 35-29 64-64 64v64c0 31-23 56-53 62l66 66h115V768H627L499 640h-38L333 768H192v-64h115l66-66c-30-6-53-31-53-62v-64c-35 0-64-29-64-64v-64L75 446l-22-60 203-66v-64H64v-64h192v-64L53 62l22-60 181 62v-64c0-35 29-64 64-64h64l64 64V448h64v-448l64-64h64c35 0 64 29 64 64v64l181-62 22 60-203 66v64zM576 512H384v64h192v-64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="calendar" unicode="" d="M768 704h-64v-96c0-18-14-32-32-32H544c-18 0-32 14-32 32v96H320v-96c0-18-14-32-32-32H160c-18 0-32 14-32 32v96H64c-35 0-64-29-64-64v-704c0-35 29-64 64-64h704c35 0 64 29 64 64V640c0 35-29 64-64 64z m0-768H64V512h704v-576zM256 640h-64V768h64v-128z m384 0h-64V768h64v-128zM320 384h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64zM192 256h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64zM192 128h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64zM192 0h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="check" unicode="" d="M768 512L256 0 0 256l96 96 160-160 416 416 96-96z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="checklist" unicode="" d="M1024 288L640-96 448 96l96 96 96-96 288 288 96-96zM365 51l51-51H128c-35 0-64 29-64 64V640c0 35 29 64 64 64h448c35 0 64-29 64-64v-416l-51 51c-25 25-66 25-91 0L365 141c-25-25-25-65 0-90zM256 576h320v64H256v-64z m0-128h320v64H256v-64z m0-128h192v64H256v-64z m-64-64h-64v-64h64v64z m0 128h-64v-64h64v64z m0 128h-64v-64h64v64z m0 128h-64v-64h64v64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="chevron-down" unicode="" d="M320 128L0 448l96 96 224-240 224 240 96-96-320-320z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="chevron-left" unicode="" d="M352 640l96-96-240-224 240-224-96-96L32 320l320 320z" horiz-adv-x="512" />
|
||||
<glyph glyph-name="chevron-right" unicode="" d="M480 320L160 0l-96 96 240 224L64 544l96 96 320-320z" horiz-adv-x="512" />
|
||||
<glyph glyph-name="chevron-up" unicode="" d="M640 256l-96-96-224 240L96 160 0 256l320 320 320-320z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="circle-slash" unicode="" d="M448 768C201 768 0 567 0 320s201-448 448-448 448 201 448 448S695 768 448 768z m0-83c83 0 160-28 222-75L158 98c-47 62-75 139-75 222 0 201 164 365 365 365z m0-730c-83 0-160 28-222 75l512 512c47-62 75-139 75-222 0-201-164-365-365-365z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="circuit-board" unicode="" d="M192 512c0 35 29 64 64 64s64-29 64-64-29-64-64-64-64 29-64 64z m512 0c0 35-29 64-64 64s-64-29-64-64 29-64 64-64 64 29 64 64z m0-384c0 35-29 64-64 64s-64-29-64-64 29-64 64-64 64 29 64 64zM832 768H320v-139c23-12 41-30 53-53h150c27 50 85 82 150 67 48-12 87-51 98-99 20-88-46-166-131-166-51 0-95 28-117 70H373c-27-51-85-82-150-66-47 11-86 50-97 97-16 65 15 123 66 150V768H64C29 768 0 739 0 704v-768c0-35 29-64 64-64l320 320h139c27 50 85 82 150 67 48-12 87-51 98-99 20-88-46-166-131-166-51 0-95 28-117 70h-75L256-128h576c35 0 64 29 64 64V704c0 35-29 64-64 64z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="clippy" unicode="" d="M128 64h256v-64H128v64z m320 384H128v-64h320v64z m128-192V384L384 192l192-192V128h320V256H576z m-288 64H128v-64h160v64zM128 128h160v64H128v-64z m576-64h64v-128c-1-18-7-33-19-45s-27-18-45-19H64c-35 0-64 29-64 64V640c0 35 29 64 64 64h192C256 775 313 832 384 832s128-57 128-128h192c35 0 64-29 64-64v-320h-64V512H64v-576h640V64zM128 576h512c0 35-29 64-64 64h-64c-35 0-64 29-64 64s-29 64-64 64-64-29-64-64-29-64-64-64h-64c-35 0-64-29-64-64z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="clock" unicode="" d="M512 320h192v-128H448c-35 0-64 29-64 64V576h128v-256z m-64 365c201 0 365-164 365-365S649-45 448-45 83 119 83 320s164 365 365 365m0 83C201 768 0 567 0 320s201-448 448-448 448 201 448 448S695 768 448 768z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="cloud-download" unicode="" d="M576 0h128l-192-192-192 192h128V320h128v-320z m192 512c0 28-58 192-288 192-155 0-288-123-288-256C65 448 0 351 0 256c0-98 64-192 192-192 28 0 170 0 192 0v83H192C88 147 83 238 83 256c0 11 3 109 109 109h83v83c0 89 100 173 205 173 163 0 200-99 205-115v-77h83c52 0 173-14 173-141 0-134-144-141-173-141H640v-83c24 0 127 0 128 0 133 0 256 74 256 224 0 156-123 224-256 224z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="cloud-upload" unicode="" d="M448 256H320l192 192 192-192H576v-320H448V256z m320 256c0 28-58 192-288 192-155 0-288-123-288-256C65 448 0 351 0 256c0-98 64-192 192-192 28 0 170 0 192 0v83H192C88 147 83 238 83 256c0 11 3 109 109 109h83v83c0 89 100 173 205 173 163 0 200-99 205-115v-77h83c52 0 173-14 173-141 0-134-144-141-173-141H640v-83c24 0 127 0 128 0 133 0 256 74 256 224 0 156-123 224-256 224z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="code" unicode="" d="M608 640l-96-96 224-224L512 96l96-96 288 320L608 640zM288 640L0 320l288-320 96 96L160 320l224 224L288 640z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="comment" unicode="" d="M832 704H64c-35 0-64-29-64-64v-512c0-35 29-64 64-64h128v-224l224 224h416c35 0 64 29 64 64V640c0 35-29 64-64 64z m0-576H384L256 0V128H64V640h768v-512z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="comment-discussion" unicode="" d="M960 704H384c-35 0-64-29-64-64v-128H64c-35 0-64-29-64-64v-384c0-35 29-64 64-64h64v-192l192 192h256c35 0 64 29 64 64V192h64l192-192V192h64c35 0 64 29 64 64V640c0 35-29 64-64 64zM576 64H288l-96-96v96H64V448h256v-192c0-35 29-64 64-64h192v-128z m384 192H832v-96l-96 96H384V640h576v-384z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="credit-card" unicode="" d="M768 256H128v64h640v-64z m256 384v-576c0-35-29-64-64-64H64c-35 0-64 29-64 64V640c0 35 29 64 64 64h896c35 0 64-29 64-64z m-64-192H64v-384h896V448z m0 192H64v-64h896v64zM384 192H128v-64h256v64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="dash" unicode="" d="M0 384v-128h512V384H0z" horiz-adv-x="512" />
|
||||
<glyph glyph-name="dashboard" unicode="" d="M512 512h-64v64h64v-64z m256-192h-64v-64h64v64zM320 512h-64v-64h64v64z m-64-192h-64v-64h64v64z m704 352l-32 32-416-320c-4 1-64 0-64 0-35 0-64-29-64-64v-64c0-35 29-64 64-64h64c35 0 64 29 64 64v59l384 357zM858 410c12-39 19-80 19-122 0-219-178-397-397-397S83 69 83 288s178 397 397 397c77 0 148-22 209-60l60 60c-76 52-169 83-269 83C215 768 0 553 0 288s215-480 480-480 480 215 480 480c0 66-13 129-38 186l-64-64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="database" unicode="" d="M384-128C171.969-128 0-70.625 0 0c0 38.625 0 80.875 0 128 0 11.125 5.562 21.688 13.562 32C56.375 104.875 205.25 64 384 64s327.625 40.875 370.438 96c8-10.312 13.562-20.875 13.562-32 0-37.062 0-76.375 0-128C768-70.625 596-128 384-128zM384 128C171.969 128 0 185.375 0 256c0 38.656 0 80.844 0 128 0 6.781 2.562 13.375 6 19.906l0 0C7.938 408 10.5 412.031 13.562 416 56.375 360.906 205.25 320 384 320s327.625 40.906 370.438 96c3.062-3.969 5.625-8 7.562-12.094l0 0c3.438-6.531 6-13.125 6-19.906 0-37.062 0-76.344 0-128C768 185.375 596 128 384 128zM384 384C171.969 384 0 441.344 0 512c0 20.219 0 41.594 0 64 0 20.344 0 41.469 0 64C0 710.656 171.969 768 384 768c212 0 384-57.344 384-128 0-19.969 0-41.156 0-64 0-19.594 0-40.25 0-64C768 441.344 596 384 384 384zM384 704c-141.375 0-256-28.594-256-64s114.625-64 256-64 256 28.594 256 64S525.375 704 384 704z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="desktop-download" unicode="" d="M256 448h192V832h128v-384h192L512 192 256 448z m704 256H704v-64h256v-512H64V640h256v64H64c-35 0-64-29-64-64v-576c0-35 29-64 64-64h342c-16-39-55-89-150-128h512c-95 39-134 89-150 128h342c35 0 64 29 64 64V640c0 35-29 64-64 64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="device-camera" unicode="" d="M960 640H448c0 35-29 64-64 64H128c-35 0-64-29-64-64-35 0-64-29-64-64v-576c0-35 29-64 64-64h896c35 0 64 29 64 64V576c0 35-29 64-64 64zM384 512H128v64h256v-64z m288-448c-124 0-224 100-224 224s100 224 224 224 224-100 224-224-100-224-224-224z m160 224c0-88-72-160-160-160s-160 72-160 160 72 160 160 160 160-72 160-160z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="device-camera-video" unicode="" d="M973 634L640 402V576c0 35-29 64-64 64H64c-35 0-64-29-64-64v-576c0-35 29-64 64-64h512c35 0 64 29 64 64V174l333-232c21-15 51 0 51 26V608c0 26-30 41-51 26z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="device-desktop" unicode="" d="M960 704H64c-35 0-64-29-64-64v-576c0-35 29-64 64-64h342c-16-39-55-89-150-128h512c-95 39-134 89-150 128h342c35 0 64 29 64 64V640c0 35-29 64-64 64z m0-576H64V640h896v-512z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="device-mobile" unicode="" d="M576 832H64C29 832 0 803 0 768v-896c0-35 29-64 64-64h512c35 0 64 29 64 64V768c0 35-29 64-64 64zM320-147c-46 0-83 37-83 83s37 83 83 83 83-37 83-83-37-83-83-83z m256 211H64V704h512v-640z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="diff" unicode="" d="M384 384h128v-64H384v-128h-64V320H192v64h128V512h64v-128zM192 0h320v64H192v-64z m288 704l224-224v-608c0-35-29-64-64-64H64c-35 0-64 29-64 64V640c0 35 29 64 64 64h416z m160-256L448 640H64v-768h576V448zM544 832S192 832 192 832v-64h320l256-256v-512h64V544L544 832z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="diff-added" unicode="" d="M832 768H64C29 768 0 739 0 704v-768c0-35 29-64 64-64h768c35 0 64 29 64 64V704c0 35-29 64-64 64z m0-832H64V704h768v-768zM384 256H192V384h192V576h128v-192h192v-128H512v-192H384V256z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="diff-ignored" unicode="" d="M832 768H64C29 768 0 739 0 704v-768c0-35 29-64 64-64h768c35 0 64 29 64 64V704c0 35-29 64-64 64z m0-832H64V704h768v-768zM288 64h-96v96l416 416h96v-96L288 64z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="diff-modified" unicode="" d="M832 768H64C29 768 0 739 0 704v-768c0-35 29-64 64-64h768c35 0 64 29 64 64V704c0 35-29 64-64 64z m0-832H64V704h768v-768zM256 320c0 106 86 192 192 192s192-86 192-192-86-192-192-192-192 86-192 192z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="diff-removed" unicode="" d="M832 768H64C29 768 0 739 0 704v-768c0-35 29-64 64-64h768c35 0 64 29 64 64V704c0 35-29 64-64 64z m0-832H64V704h768v-768zM704 256H192V384h512v-128z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="diff-renamed" unicode="" d="M384 256H192V384h192V576l320-256-320-256V256z m512 448v-768c0-35-29-64-64-64H64c-35 0-64 29-64 64V704c0 35 29 64 64 64h768c35 0 64-29 64-64z m-64 0H64v-768h768V704z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="ellipsis" unicode="" d="M704 512H64c-35 0-64-29-64-64v-256c0-35 29-64 64-64h640c35 0 64 29 64 64V448c0 35-29 64-64 64zM256 256H128V384h128v-128z m192 0H320V384h128v-128z m192 0H512V384h128v-128z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="eye" unicode="" d="M516 704C192 704 0 320 0 320s192-384 516-384c316 0 508 384 508 384S832 704 516 704z m-4-640c-141 0-256 114-256 256 0 141 115 256 256 256 142 0 256-115 256-256 0-142-114-256-256-256z m128 256c0-71-57-128-128-128s-128 57-128 128 57 128 128 128 128-57 128-128z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="file-binary" unicode="" d="M256 64h64v-64H128v64h64V192h-64v64h128v-192z m512 480v-608c0-35-29-64-64-64H64c-35 0-64 29-64 64V704c0 35 29 64 64 64h480l224-224z m-64-32L512 704H64v-768h640V512z m-192 64H384v-64h64v-128h-64v-64h192v64h-64V576z m-384 0h192v-256H128V576z m64-192h64V512h-64v-128z m192-128h192v-256H384V256z m64-192h64V192h-64v-128z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="file-code" unicode="" d="M544 768H64C29 768 0 739 0 704v-768c0-35 29-64 64-64h640c35 0 64 29 64 64V544L544 768z m160-832H64V704h448l192-192v-576zM320 385l-96-97 96-96-32-64-160 160 160 160 32-63z m160 63l160-160-160-160-32 63 96 97-96 96 32 64z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="file-directory" unicode="" d="M832 576H448v64c0 42-20 64-64 64H64c-35 0-64-29-64-64v-640c0-35 29-64 64-64h768c35 0 64 29 64 64V512c0 35-29 64-64 64z m-448 0H64v64h320v-64z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="file-media" unicode="" d="M384 512h128v-128H384V512z m384 32v-608c0-35-29-64-64-64H64c-35 0-64 29-64 64V704c0 35 29 64 64 64h480l224-224z m-64-32L512 704H64v-704l192 320 128-256 128 128 192-192V512z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="file-pdf" unicode="" d="M544 768H64C29 768 0 739 0 704v-768c0-35 29-64 64-64h640c35 0 64 29 64 64V544L544 768zM64 704h256c-7-2-13-6-20-13-6-6-11-16-15-30-7-25-9-57-6-94s11-75 22-115c-15-47-39-103-71-170s-51-106-58-118c-9-3-23-9-44-19-21-9-42-23-64-41V704z m283-307c29-72 54-117 75-134s41-29 60-34c-41-6-79-13-116-21-36-8-75-21-116-38 1 1 14 28 39 80s45 101 58 147z m357-461H96c-4 0-8 1-11 2 13 4 29 13 47 28 29 24 67 74 114 152 20 8 37 15 52 20l27 9c29 8 60 15 92 21 32 5 64 10 95 13 29-14 58-25 89-34 31-8 58-13 79-15 9 0 17 1 24 2v-198z m0 311c-12 7-26 13-41 18-15 4-31 6-48 7-25 0-51-2-79-5-15 4-36 18-63 41s-55 73-84 149c8 53 12 95 13 126s1 47 0 48c3 26-2 45-13 56s-24 17-39 17h162l192-192v-265z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="file-submodule" unicode="" d="M640 384H256v-448h576c35 0 64 29 64 64V320H640v64z m-64-128H320v64h256v-64z m256 320H448v64c0 42-20 64-64 64H64c-35 0-64-29-64-64v-640c0-35 29-64 64-64h128V384c0 35 29 64 64 64h384c35 0 64-29 64-64h192V512c0 35-29 64-64 64z m-448 0H64v64h320v-64z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="file-symlink-directory" unicode="" d="M832 576H448v64c0 42-20 64-64 64H64c-35 0-64-29-64-64v-640c0-35 29-64 64-64h768c35 0 64 29 64 64V512c0 35-29 64-64 64zM64 640h320v-64H64v64z m384-576V192c-63 1-118-14-163-45s-76-80-93-147c1 105 25 184 72 239 47 54 108 81 184 81V448l256-192-256-192z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="file-symlink-file" unicode="" d="M544 768H64C29 768 0 739 0 704v-768c0-35 29-64 64-64h640c35 0 64 29 64 64V544L544 768z m160-832H64V704h448l192-192v-576zM384 544l256-192-256-192V288c-63 1-118-14-163-45s-76-80-93-147c1 105 25 184 72 239 47 54 108 81 184 81V544z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="file-text" unicode="" d="M384 512H128v64h256v-64zM128 320h448v64H128v-64z m0-128h448v64H128v-64z m0-128h448v64H128v-64z m640 480v-608c0-35-29-64-64-64H64c-35 0-64 29-64 64V704c0 35 29 64 64 64h480l224-224z m-64-32L512 704H64v-768h640V512z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="file-zip" unicode="" d="M544 768H64C29 768 0 739 0 704v-768c0-35 29-64 64-64h640c35 0 64 29 64 64V544L544 768z m160-832H64V704h192v-64h64v64h192l192-192v-576zM320 576v64h64v-64h-64z m-64 0h64v-64h-64v64z m64-128v64h64v-64h-64z m-64 0h64v-64h-64v64z m64-128v64h64v-64h-64z m-64-82c-38-22-64-63-64-110v-64h256v64c0 71-57 128-128 128v64h-64v-82z m128-46v-64H256v64h128z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="flame" unicode="" d="M323 812c52-139 26-216-33-276-63-67-163-117-232-215-93-131-109-418 226-493-141 74-171 289-19 423-39-130 34-213 124-183 89 30 147-34 145-107-1-50-20-92-72-116 219 38 306 219 306 356 0 182-162 206-80 359-97-8-130-72-121-176 6-69-65-115-119-85-43 26-42 76-4 114 80 79 112 262-120 398l-1 1z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="fold" unicode="" d="M448 256l192-192H512v-192H384V64H256l192 192z m192 384H512V832H384v-192H256l192-192 192 192z m256-128c0 35-29 64-64 64H672l-64-64h192L672 384H224L96 512h192l-64 64H64c-35 0-64-29-64-64l160-160L0 192c0-35 29-64 64-64h160l64 64H96l128 128h448l128-128H608l64-64h160c35 0 64 29 64 64L736 352l160 160z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="gear" unicode="" d="M896 271V373l-124 41-29 70 56 118-72 72-116-58-70 29-44 123H395l-40-124-71-29-118 56-72-72 58-116-29-70L0 369v-102l124-41 29-70-56-118 72-72 116 58 70-29 44-123h102l40 124 71 29 118-56 72 72-59 116 30 70 123 44zM448 128c-106 0-192 86-192 192s86 192 192 192 192-86 192-192-86-192-192-192z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="gift" unicode="" d="M832 576h-88c12 21 21 43 23 58 4 43-7 78-33 103-23 24-52 31-87 31-3 0-5 0-7 0-34-1-71-16-98-37s-47-46-62-77c-15 31-35 56-62 77s-64 37-98 37c-1 0-2 0-2 0-36 0-68-6-92-31-26-25-37-60-33-103 2-15 11-37 23-58h-88c-35 0-64-29-64-64v-192h64v-320c0-35 29-64 64-64h576c35 0 64 29 64 64V320h64V512c0 35-29 64-64 64z m-306 56c11 23 27 43 48 59 19 15 46 25 67 26h6c29 0 42-7 51-16s21-25 19-61c-3-12-16-39-32-64H500l26 56z m-264 69c8 8 20 16 58 16 20 0 46-11 66-26 21-16 37-35 48-59l27-56H275c-16 25-29 52-32 64-2 36 10 52 19 61z m186-701H192V320h256v-320z m0 384H128V512h320v-128z m320-384H512V320h256v-320z m64 384H512V512h320v-128z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="gist" unicode="" d="M480 512l160-160-160-160-48 48 112 112-112 112 48 48z m-192 0L128 352l160-160 48 48-112 112 112 112-48 48zM0 0V704c0 35 29 64 64 64h640c35 0 64-29 64-64v-704c0-35-29-64-64-64H64c-35 0-64 29-64 64z m64 0h640V704H64v-704z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="gist-secret" unicode="" d="M512 160l64-224H320l64 224-48 96h224l-48-96z m128 288H256l-128-64h640l-128 64z m-64 256l-128-64-128 64-64-192h384l-64 192z m258-496l-194 48 64-128-128-192h206c29 0 55 20 62 48l36 146c9 34-12 69-46 78z m-578 48L62 208c-34-9-55-44-46-78l36-146c7-28 33-48 62-48h206L192 128l64 128z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="git-branch" unicode="" d="M640 512c0 71-57 128-128 128s-128-57-128-128c0-47 26-88 64-110v-19c-1-33-15-63-40-88s-55-39-88-40c-53-1-95-10-128-29V530c38 22 64 63 64 110 0 71-57 128-128 128S0 711 0 640c0-47 26-88 64-110v-420C26 88 0 47 0 0c0-71 57-128 128-128s128 57 128 128c0 34-13 64-34 87 6 4 31 26 38 30 16 7 36 11 60 11 67 3 125 29 176 80s77 127 80 193h-1c39 23 65 64 65 111zM128 717c42 0 77-35 77-77s-35-77-77-77-77 35-77 77 35 77 77 77z m0-794c-42 0-77 35-77 77s35 77 77 77 77-35 77-77-35-77-77-77z m384 512c-42 0-77 35-77 77s35 77 77 77 77-35 77-77-35-77-77-77z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="git-commit" unicode="" d="M695 384c-29 110-128 192-247 192s-218-82-247-192H0v-128h201c29-110 128-192 247-192s218 82 247 192h201V384H695zM448 179c-78 0-141 63-141 141s63 141 141 141 141-63 141-141-63-141-141-141z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="git-compare" unicode="" d="M320 64h-64c-17 1-31 7-44 20s-19 27-20 44V530c38 22 64 63 64 110 0 71-57 128-128 128S0 711 0 640c0-47 26-88 64-110 0-111 0-402 0-402 2-50 22-94 60-132s82-58 132-60c0 0 65 0 64 0v-128l192 192-192 192v-128zM128 717c42 0 77-35 77-77s-35-77-77-77-77 35-77 77 35 77 77 77z m704-607c0 111 0 402 0 402-2 50-22 94-60 132s-82 58-132 60c0 0-65 0-64 0V832L384 640l192-192V576h64c17-1 31-7 44-20s19-27 20-44v-402c-38-22-64-63-64-110 0-71 57-128 128-128s128 57 128 128c0 47-26 88-64 110z m-64-187c-42 0-77 35-77 77s35 77 77 77 77-35 77-77-35-77-77-77z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="git-merge" unicode="" d="M640 384c-47 0-88-26-111-65v1c-67 1-145 23-200 65-48 37-96 103-121 156 29 23 48 59 48 99 0 71-57 128-128 128S0 711 0 640c0-47 26-88 64-110v-420C26 88 0 47 0 0c0-71 57-128 128-128s128 57 128 128c0 47-26 88-64 110V341c43-45 92-81 147-108s130-40 190-41v1c23-39 64-65 111-65 71 0 128 57 128 128s-57 128-128 128zM205 0c0-42-35-77-77-77s-77 35-77 77 35 77 77 77 77-35 77-77z m-77 563c-42 0-77 35-77 77s35 77 77 77 77-35 77-77-35-77-77-77z m512-384c-42 0-77 35-77 77s35 77 77 77 77-35 77-77-35-77-77-77z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="git-pull-request" unicode="" d="M704 110c0 111 0 402 0 402-2 50-22 94-60 132s-82 58-132 60c0 0-65 0-64 0V832L256 640l192-192V576h64c17-1 31-7 44-20s19-27 20-44v-402c-38-22-64-63-64-110 0-71 57-128 128-128s128 57 128 128c0 47-26 88-64 110z m-64-187c-42 0-77 35-77 77s35 77 77 77 77-35 77-77-35-77-77-77zM256 640c0 71-57 128-128 128S0 711 0 640c0-47 26-88 64-110 0-99 0-356 0-420-38-22-64-63-64-110 0-71 57-128 128-128s128 57 128 128c0 47-26 88-64 110V530c38 22 64 63 64 110z m-51-640c0-42-35-77-77-77s-77 35-77 77 35 77 77 77 77-35 77-77z m-77 563c-42 0-77 35-77 77s35 77 77 77 77-35 77-77-35-77-77-77z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="globe" unicode="" d="M448 768C201 768 0 567 0 320s201-448 448-448c31 0 60 3 88 9-11 5-13 47-1 70 12 26 52 93 13 115s-28 32-52 58-14 30-16 37c-5 22 23 57 25 60 1 4 1 17 0 21 0 5-17 14-22 15-4 0-7-7-13-8s-32 16-38 21-9 15-17 22c-8 8-9 2-21 7s-51 20-82 31c-31 12-33 30-33 42-1 13-19 30-27 43-9 13-10 30-13 26s16-50 13-52c-3-1-10 13-19 24-9 12 9 6-19 61s9 83 11 112 24-11 12 8 0 57-9 71c-8 14-56-16-56-16 1 14 44 37 74 59s50 4 74-3c25-8 26-6 18 3-8 8 4 11 23 8 18-3 24-26 53-23 30 2 3-6 7-14s-4-7-24-19c-19-13 1-14 35-39s24 16 20 35 25 4 25 4c21-14 17-1 32-5s58-41 58-41c-53-28-20-31-11-38s-18-19-18-19c-11 11-12-1-19-5s-1-14-1-14c-36-6-28-44-27-53 0-9-24-23-30-37-6-13 16-41 4-42-12-2-22 42-84 26-19-5-60-26-38-69 23-44 59 12 71 6s-4-34-1-35 34-1 36-39 49-34 59-35c11 0 45 28 49 29 4 2 24 18 66-6 42-23 63-20 77-30s5-30 18-37 68 2 82-20-56-134-78-146-31-41-54-59-52-41-81-58c-26-15-30-42-42-51 201 45 351 224 351 438 0 247-201 448-448 448z m105-420c-6-2-18-14-50 5-31 19-52 15-55 18 0 0-3 7 11 9 28 3 63-26 71-26s12 8 26 3 3-8-3-9zM406 723c-3 2 2 5 6 9 2 2 1 7 3 9 7 7 39 16 33-2-7-17-37-19-42-16z m79-57c-12 1-37 3-33 9 19 18-6 24-22 24-16 1-22 10-14 12s39-1 45-5c5-4 33-16 35-24 1-8 0-16-11-16z m94 3c-9-6-53 26-61 33-36 31-57 20-64 26s-5 12 7 22 44-4 64-6c19-2 42-17 42-35 1-16 21-32 12-40z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="graph" unicode="" d="M1024-64v-64H0V832h64v-896h960z m-704 64H192V320h128v-320z m256 0H448V640h128v-640z m256 0H704V448h128v-448z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="heart" unicode="♥" d="M717 576c-33 40-80 61-141 64-62 0-108-27-141-64s-50-59-51-64c-1 5-18 27-51 64s-75 64-141 64c-61-3-108-24-141-64-33-39-50-82-51-128 0-33 6-97 43-171s150-188 341-341c191 153 305 267 342 341s42 139 42 171c-1 46-18 89-51 129z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="history" unicode="" d="M512 0H384V448h320v-128H512v-320zM448 768c-140 0-264-65-346-166L0 704v-256h256l-96 96c67 85 171 141 288 141 201 0 365-164 365-365S649-45 448-45 83 119 83 320c0 22 2 43 6 64H5c-3-21-5-42-5-64 0-247 201-448 448-448s448 201 448 448S695 768 448 768z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="home" unicode="" d="M1024 256L832 448V704H704v-128L512 768 0 256h128l64-320c0-35 29-64 64-64h512c35 0 64 29 64 64l64 320h128zM768-64H576V192H448v-256H256l-76 404 332 332 332-332-76-404z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="horizontal-rule" unicode="" d="M64 384h128v-128h64V640h-64v-192H64V640H0v-384h64V384z m576-128V384h-64v-128h64z m0 192V576h-64v-128h64z m-192 0V576h128v64H384v-384h64V384h128v64H448zM0 0h640V128H0v-128z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="hubot" unicode="" d="M192 448c-35 0-64-29-64-64v-128c0-35 29-64 64-64h512c35 0 64 29 64 64V384c0 35-29 64-64 64H192z m512-112l-80-80h-96l-80 80-80-80h-96l-80 80v48h48l80-80 80 80h96l80-80 80 80h48v-48zM320 128h256v-64H320v64z m128 576C201 704 0 518 0 288v-288c0-35 29-64 64-64h768c35 0 64 29 64 64V288c0 230-201 416-448 416z m384-704H64V288c0 198 169 358 384 358s384-160 384-358v-288z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="inbox" unicode="" d="M896 256l-72 457c-5 31-32 55-64 55H136c-32 0-59-24-64-55L0 256v-320c0-35 29-64 64-64h768c35 0 64 29 64 64V256z m-210-35l-28-57c-11-22-33-36-58-36H295c-24 0-46 14-57 35l-28 58c-11 21-33 35-57 35H64l64 448h640l64-448h-88c-25 0-47-14-58-35z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="info" unicode="" d="M403 468c-12 12-18 27-18 45s6 33 18 45 27 18 45 18 33-6 45-18 18-27 18-45-6-33-18-45-27-19-45-19-33 7-45 19z m109-147c-1 16-7 31-20 44-13 12-27 19-44 20h-64c-17-1-31-8-44-20-13-13-19-28-20-44h64v-192c1-17 7-32 20-44 13-13 27-20 44-20h64c17 0 31 7 44 20 13 12 19 27 20 44h-64V321z m-64 364C247 685 83 522 83 321s164-365 365-365 365 163 365 365-164 364-365 364m0 84c247 0 448-201 448-448S695-127 448-127 0 73 0 321 201 769 448 769z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="issue-closed" unicode="" d="M448 192h128v-128H448V192z m128 384H448v-320h128V576z m96-96l-64-64 160-160 256 288-64 64-192-224-96 96zM512-45c-201 0-365 164-365 365s164 365 365 365c117 0 221-56 288-141l59 59C777 704 652 768 512 768 265 768 64 567 64 320s201-448 448-448 448 201 448 448l-97-97c-42-154-183-268-351-268z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="issue-opened" unicode="" d="M448 685c201 0 365-164 365-365S649-45 448-45 83 119 83 320s164 365 365 365m0 83C201 768 0 567 0 320s201-448 448-448 448 201 448 448S695 768 448 768z m64-192H384v-320h128V576z m0-384H384v-128h128V192z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="issue-reopened" unicode="" d="M512 256H384V576h128v-320zM384 64h128V192H384v-128z m405 128H640l96-96c-67-85-171-141-288-141-201 0-365 164-365 365 0 22 2 43 6 64H5c-3-21-5-42-5-64 0-247 201-448 448-448 140 0 264 65 346 166l102-102V192H789zM107 448h149l-96 96c67 85 171 141 288 141 201 0 365-164 365-365 0-22-2-43-6-64h84c3 21 5 42 5 64 0 247-201 448-448 448-140 0-264-65-346-166L0 704v-256h107z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="italic" unicode="" d="M180 512h127L192-64H64l116 576z m23 173c0 45 37 83 85 83 36 0 72-24 72-66 0-48-38-83-85-83-37 0-72 24-72 66z" horiz-adv-x="384" />
|
||||
<glyph glyph-name="jersey" unicode="" d="M224 448l-32-32v-320l32-32h128l32 32V416l-32 32H224z m96-320h-64V384h64v-256z m401 464c-14 88-20 168-17 240H513c0-17-8-31-25-44-16-13-40-19-72-19s-56 6-72 19c-15 13-23 27-23 44H128c3-72-2-152-16-240-13-88-51-136-112-144v-576c1-17 7-31 20-44s27-19 44-20h704c17 1 31 7 44 20s19 27 20 44V448c-61 8-98 56-112 144z m47-720H64V384c57 32 95 80 110 144s20 144 18 240h64c-1-50 10-94 33-132 23-37 65-57 128-60 63 1 105 21 128 60 23 38 32 82 31 132h64c1-91 8-163 21-216 13-52 44-128 107-168v-512zM480 448l-32-32v-320l32-32h128l32 32V416l-32 32H480z m96-320h-64V384h64v-256z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="key" unicode="" d="M821 693c-48 48-108 73-181 75-72-2-133-27-181-75s-72-108-74-181c0-19 2-38 6-57L0 64v-64l64-64h128l64 64v64h64v64h64v64h128l70 71c19-5 38-7 58-7 73 2 133 27 181 75s73 108 75 181c-2 73-27 133-75 181zM704 488c-49 0-88 39-88 88s39 88 88 88 88-39 88-88-39-88-88-88z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="keyboard" unicode="" d="M640 512h-64v64h64v-64z m-448-64h-64v-64h64v64z m320 128h-64v-64h64v64z m-256 0H128v-64h128v64z m512-448h128v64H768v-64zM512 384h64v64h-64v-64zM256 192H128v-64h128v64z m512 384h-64v-64h64v64z m128 0h-64v-64h64v64zM768 256h128V448H768v-192z m256 384v-576c0-35-29-64-64-64H64c-35 0-64 29-64 64V640c0 35 29 64 64 64h896c35 0 64-29 64-64z m-64 0H64v-576h896V640zM384 384h64v64h-64v-64z m0 192h-64v-64h64v64zM256 384h64v64h-64v-64z m64-256h384v64H320v-64z m320 256h64v64h-64v-64z m-448-64h-64v-64h64v64z m320 0v-64h64v64h-64z m-128 0v-64h64v64h-64z m-64 0h-64v-64h64v64z m320-64h64v64h-64v-64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="law" unicode="" d="M448 576c-53 0-96 43-96 96s43 96 96 96 96-43 96-96-43-96-96-96z m448-384c0-71-57-128-128-128h-64c-71 0-128 57-128 128l128 256h-64c-35 0-64 29-64 64h-64v-512c27 0 64-29 64-64h64c27 0 64-29 64-64H192c0 35 37 64 64 64h64c0 35 37 64 64 64h2l-2 512h-64c0-35-29-64-64-64h-64l128-256c0-71-57-128-128-128h-64C57 64 0 121 0 192l128 256H64v64h192c0 35 29 64 64 64h256c35 0 64-29 64-64h192v-64h-64l128-256zM160 384L64 192h192l-96 192z m672-192l-96 192-96-192h192z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="light-bulb" unicode="" d="M352 832C159 832 0 692 0 512c0-59 35-144 64-192 86-144 114-178 128-256v-64h320v64c14 78 42 112 128 256 29 48 64 133 64 192C704 692 545 832 352 832z m233-479c-16-28-30-51-43-71-55-90-80-132-93-207-1-3-1-7-1-11H256c0 4 0 8-1 11-13 75-38 117-93 207-13 20-27 43-43 71-27 45-55 117-55 159C64 653 193 768 352 768c78 0 151-27 206-76 53-48 82-112 82-180 0-42-28-114-55-159zM192-64h320c-15-73-83-128-160-128s-145 55-160 128z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="link" unicode="" d="M256 256h64v-64h-64c-96 0-192 108-192 224s99 224 192 224h256c93 0 192-108 192-224 0-90-58-174-128-208v74c37 29 64 81 64 134 0 82-65 160-128 160H256c-63 0-128-78-128-160s64-160 128-160z m576 192h-64v-64h64c64 0 128-78 128-160s-65-160-128-160H576c-63 0-128 78-128 160 0 53 27 105 64 134v74c-70-34-128-118-128-208 0-116 99-224 192-224h256c93 0 192 108 192 224s-96 224-192 224z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="link-external" unicode="" d="M704 192h64v-192c0-35-29-64-64-64H64c-35 0-64 29-64 64V640c0 35 29 64 64 64h192v-64H64v-640h640V192zM384 704l144-144-208-208 96-96 208 208 144-144V704H384z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="list-ordered" unicode="" d="M768 0c0-38 0-64-38-64H294c-38 0-38 26-38 64s0 64 38 64h436c38 0 38-26 38-64zM294 576h436c38 0 38 26 38 64s0 64-38 64H294c-38 0-38-26-38-64s0-64 38-64z m436-192H294c-38 0-38-26-38-64s0-64 38-64h436c38 0 38 26 38 64s0 64-38 64zM128 768H82C63 756 45 752 16 746v-42h48v-137H10v-55h182v55h-64V768z m16-520c-11 0-29-2-42-4 34 36 73 80 73 121-1 50-36 83-87 83-38 0-62-13-88-41l37-37c12 12 24 24 41 24 18 0 31-10 31-33 0-34-49-77-109-132v-37h192l-6 56h-42z m-5-242v2c28 12 41 30 41 55 0 45-36 71-92 71-31 0-57-12-82-33l35-41c16 13 28 20 44 20 17 0 27-8 27-23 0-17-13-28-55-28v-48c53 0 63-11 63-30 0-16-15-24-37-24-18 0-36 9-52 24L0-92c19-23 49-36 90-36 53 0 98 26 98 74 0 32-20 52-49 60z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="list-unordered" unicode="" d="M128 0c0-38 0-64-38-64H38c-38 0-38 26-38 64s0 64 38 64h52c38 0 38-26 38-64z m166 576h436c38 0 38 26 38 64s0 64-38 64H294c-38 0-38-26-38-64s0-64 38-64zM90 384H38c-38 0-38-26-38-64s0-64 38-64h52c38 0 38 26 38 64s0 64-38 64z m0 320H38c-38 0-38-26-38-64s0-64 38-64h52c38 0 38 26 38 64s0 64-38 64z m640-320H294c-38 0-38-26-38-64s0-64 38-64h436c38 0 38 26 38 64s0 64-38 64z m0-320H294c-38 0-38-26-38-64s0-64 38-64h436c38 0 38 26 38 64s0 64-38 64z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="location" unicode="" d="M384 832C172 832 0 672 0 480c0-289 384-672 384-672s384 383 384 672C768 672 596 832 384 832z m0-931C265 31 64 292 64 480 64 639 208 768 384 768c86 0 167-31 228-87 59-55 92-126 92-201 0-188-201-449-320-579z m128 579c0-71-57-128-128-128s-128 57-128 128 57 128 128 128 128-57 128-128z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="lock" unicode="" d="M256 0h-64v64h64v-64z m512 384v-448c0-35-29-64-64-64H64c-35 0-64 29-64 64V384c0 35 29 64 64 64h64V576C128 717 243 832 384 832s256-115 256-256v-128h64c35 0 64-29 64-64z m-525 64h282V576c0 78-63 141-141 141s-141-63-141-141v-128z m461-64H128v-448h576V384z m-448-64h-64v-64h64v64z m0-128h-64v-64h64v64z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="logo-gist" unicode="" d="M301 401h157v-257c-35-17-105-22-162-22-164 0-222 141-222 323S132 769 296 769c82 0 132-15 210-47V790C465 811 400 832 296 832 72 832 0 660 0 446s71-386 296-386c105 0 180 17 230 41V465H301v-64z m409-238V572h-67v-402c0-80 37-110 110-110v57c-31 0-43 10-43 45v1z m16 558c0 28-21 50-50 50s-49-22-49-50 21-50 49-50 50 22 50 50z m278-364c-96 8-114 31-114 75 0 49 21 86 120 86 67 0 106-10 145-23v60c-44 19-97 25-144 25-141 0-187-77-187-148 0-69 30-120 175-133 99-8 113-40 113-86 0-47-28-91-132-91-71 0-119 12-149 23v-60c32-13 101-25 149-25 152 0 201 77 201 154 0 82-34 130-176 143h-1z m549 158v55h-155V730l-69-20v-135l-100-28v-31h100v-320c0-98 76-136 160-136 12 0 33 1 44 3v57c-12-2-26-2-39-2-62 0-96 25-96 86V516h155v-1z" horiz-adv-x="1600" />
|
||||
<glyph glyph-name="logo-github" unicode="" d="M553 500H312c-7 0-12-5-12-11v-118c0-6 5-11 12-11h94v-147s-21-7-80-7c-69 0-165 25-165 237s101 239 195 239c81 0 116-14 139-21 7-2 13 5 13 11l27 114c0 3-1 6-4 9-9 6-65 37-205 37C165 832 0 764 0 435s189-379 348-379c132 0 212 57 212 57 3 1 4 6 4 8V489c0 6-5 11-12 11h1zM1773 804h-136c-6 0-11-5-11-11v-262h-212V793c0 6-5 11-11 11h-136c-6 0-11-5-11-11v-711c0-6 6-11 11-11h136c6 0 11 5 11 11V386h212l-1-304c0-6 5-11 11-11h136c6 0 11 5 11 11V793c0 6-5 11-11 11h1zM716 788c-49 0-88-39-88-88s39-88 88-88c48 0 87 39 87 88s-39 88-87 88z m78-227c0 6-5 11-11 11H647c-6 0-11-6-11-13 0 0 0-395 0-470 0-13 8-17 19-17 0 0 58 0 123 0 13 0 16 6 16 17 0 25 0 471 0 471v1z m1505 10h-134c-7 0-11-5-11-12v-348s-35-25-83-25-62 22-62 70c0 47 0 304 0 304 0 6-5 11-11 11h-137c-6 0-11-5-11-11 0 0 0-186 0-327s79-176 187-176c89 0 161 49 161 49s3-25 5-29c1-3 6-6 10-6h86c7 0 11 5 11 11l1 478c0 6-5 11-12 11z m369 16c-77 0-129-34-129-34V794c0 6-5 11-11 11h-136c-6 0-11-5-11-11l-1-711c0-6 6-11 12-11h95c4 0 7 1 9 5 3 4 6 33 6 33s56-53 161-53c124 0 195 63 195 282s-113 248-190 248z m-53-401c-47 1-78 23-78 23V434s31 19 69 22c49 5 96-10 96-126 0-122-21-146-87-144z m-1429 3c-6 0-21-3-37-3-50 0-67 23-67 53s0 200 0 200h102c6 0 10 5 10 12V560c0 6-5 11-10 11h-102V706c0 5-3 8-9 8H935c-6 0-9-3-9-8v-139s-70-17-74-18c-5-1-8-6-8-11v-87c0-7 5-12 11-12h71s0-92 0-210c0-156 109-172 183-172 34 0 75 11 81 14 4 1 6 6 6 10v96c0 7-5 12-11 12h1z" horiz-adv-x="2880" />
|
||||
<glyph glyph-name="mail" unicode="" d="M0 576v-512c0-35 29-64 64-64h768c35 0 64 29 64 64V576c0 35-29 64-64 64H64c-35 0-64-29-64-64z m832 0L448 256 64 576h768zM64 480l256-192L64 96V480z m64-416l224 192 96-96 96 96 224-192H128z m704 32L576 288l256 192v-384z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="mail-read" unicode="" d="M384 512H256v64h128v-64z m192-64H256v-64h320v64z m320 31v-543c0-35-29-64-64-64H64c-35 0-64 29-64 64V479c0 21 10 40 27 52l101 72v37c0 35 29 64 64 64h77L448 832l179-128h77c35 0 64-29 64-64v-37l101-72c17-12 27-31 27-52zM192 352l256-160 256 160V640H192v-288zM64-32l288 192L64 352v-384z m704-32L448 128 128-64h640z m64 416L544 160l288-192V352z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="mail-reply" unicode="" d="M384 672l-384-288 384-288v192c111 0 329-61 384-280 0 291-196 451-384 472v192z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="mark-github" unicode="" d="M512 832C229.252 832 0 602.748 0 320c0-226.251 146.688-418.126 350.155-485.813 25.593-4.686 34.937 11.125 34.937 24.626 0 12.188-0.469 52.562-0.718 95.314-128.708-23.46-161.707 31.541-172.469 60.373-5.525 14.809-30.407 60.249-52.398 72.263-17.988 9.828-43.26 33.237-0.917 33.735 40.434 0.476 69.348-37.308 78.471-52.75 45.938-77.749 119.876-55.627 148.999-42.5 4.654 32.999 17.902 55.627 32.501 68.373-113.657 12.939-233.22 56.875-233.22 253.063 0 55.94 19.968 101.561 52.658 137.404-5.22 12.999-22.844 65.095 5.063 135.563 0 0 42.937 13.749 140.811-52.501 40.811 11.406 84.594 17.031 128.124 17.22 43.499-0.188 87.314-5.874 128.188-17.28 97.689 66.311 140.686 52.501 140.686 52.501 28-70.532 10.375-122.564 5.124-135.499 32.811-35.844 52.626-81.468 52.626-137.404 0-196.686-119.751-240-233.813-252.686 18.439-15.876 34.748-47.001 34.748-94.748 0-68.437-0.686-123.627-0.686-140.501 0-13.625 9.312-29.561 35.25-24.562C877.436-97.99800000000005 1024 93.87400000000002 1024 320 1024 602.748 794.748 832 512 832z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="markdown" unicode="" d="M950.154 640H73.846C33.127 640 0 606.873 0 566.154v-492.308C0 33.125 33.127 0 73.846 0h876.308c40.721 0 73.846 33.125 73.846 73.846V566.154C1024 606.873 990.875 640 950.154 640zM576 128.125L448 128V320l-96-123.077L256 320v-192H128V512h128l96-128 96 128 128 0.125V128.125zM767.091 96.125L608 320h96V512h128v-192h96L767.091 96.125z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="megaphone" unicode="" d="M640 768c-11 0-23-3-33-9-92-56-319-220-415-247-88 0-192-43-192-160s104-160 192-160c19-5 41-15 64-26v-294h128V93c86-55 172-117 223-148 10-6 22-9 33-9 33 0 64 27 64 64V704c0 37-31 64-64 64z m0-768c-24 15-57 37-96 64-10 7-21 14-32 22V620c10 7 20 13 30 20 39 26 74 49 98 64v-704z m128 384h256v-64H768v64z m0-128l256-128v-64L768 192v64z m256 384v-64L768 448v64l256 128z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="mention" unicode="" d="M421-128c80 0 161 20 228 60l-27 60c-54-33-121-53-194-53-207 0-361 133-361 366C67 585 274 765 488 765c221 0 334-140 334-333 0-153-86-247-160-247-67 0-87 47-67 140l47 240h-67l-7-46c-26 40-60 53-100 53-140 0-234-153-234-280 0-107 60-167 147-167 54 0 107 34 147 80 7-60 60-93 127-93 107 0 241 107 241 320C896 665 742 832 501 832 234 832 0 619 0 299c0-280 187-427 421-427z m-20 320c-47 0-87 33-87 107 0 93 60 206 154 206 33 0 54-13 80-53l-33-193c-40-47-80-67-114-67z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="milestone" unicode="" d="M512 704H384V832h128v-128z m256-320H128c-35 0-64 29-64 64V576c0 35 29 64 64 64h640l128-128-128-128zM512 576H384v-128h128V576z m-128-768h128V320H384v-512z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="mirror" unicode="" d="M992 531L544 832 96 531c-19-12-32-29-32-51v-672l480 256 480-256V480c0 22-13 39-32 51z m-32-627L576 112v80h-64v-80L128-96V480L512 736v-288h64V736l384-256v-576zM384 384h320V512l192-192-192-192V256H384v-128L192 320l192 192v-128z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="mortar-board" unicode="" d="M501 244l-245 76s0-96 0-160 115-96 256-96 256 32 256 96 0 160 0 160l-245-76c-7-2-15-2-23 0h1z m18 409c-4 1-9 1-13 0l-489-152c-21-7-21-36 0-43l111-35v-113c-19-11-32-32-32-55 0-12 3-23 9-32-5-9-9-20-9-32v-165c0-35 128-35 128 0v165c0 12-3 23-9 32 5 9 9 20 9 32 0 24-13 44-32 55v93l313-98c4-1 9-1 13 0l489 152c21 7 21 36 0 43l-488 153z m-6-205c-35 0-64 14-64 32s29 32 64 32 64-14 64-32-29-32-64-32z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="mute" unicode="" d="M512 652v-664c0-43-52-64-82-34L192 192H64c-35 0-64 29-64 64V384c0 35 29 64 64 64h128l238 238c30 30 82 9 82-34z m482-206l-68 68-126-126-126 126-68-68 126-126-126-126 68-68 126 126 126-126 68 68-126 126 126 126z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="no-newline" unicode="" d="M1024 512v-192c0-35-29-64-64-64H768v-128L576 320l192 192v-128h128V512h128zM512 320c0-141-115-256-256-256S0 179 0 320s115 256 256 256 256-115 256-256zM96 214l266 266c-31 20-67 32-106 32-106 0-192-86-192-192 0-39 12-75 32-106z m352 106c0 39-12 75-32 106L150 160c31-20 67-32 106-32 106 0 192 86 192 192z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="octoface" unicode="" d="M940.812 554.312c8.25 20.219 35.375 101.75-8.562 211.906 0 0-67.375 21.312-219.875-82.906C648.5 700.875 579.875 703.5 512 703.5c-67.906 0-136.438-2.625-200.5-20.25C159.031 787.531 91.719 766.219 91.719 766.219 47.812 656 74.938 574.531 83.188 554.312 31.5 498.438 0 427.125 0 339.656 0 10.437999999999988 213.25-64 510.844-64 808.562-64 1024 10.437999999999988 1024 339.656 1024 427.125 992.5 498.438 940.812 554.312zM512-1c-211.406 0-382.781 9.875-382.781 214.688 0 48.938 24.062 94.595 65.344 132.312 68.75 62.969 185.281 29.688 317.438 29.688 132.25 0 248.625 33.281 317.438-29.625 41.312-37.78 65.438-83.312 65.438-132.312C894.875 8.875 723.375-1 512-1zM351.156 319.562c-42.469 0-76.906-51.062-76.906-114.188s34.438-114.312 76.906-114.312c42.375 0 76.812 51.188 76.812 114.312S393.531 319.562 351.156 319.562zM672.875 319.562C630.5 319.562 596 268.5 596 205.375s34.5-114.312 76.875-114.312 76.812 51.188 76.812 114.312C749.75 268.5 715.312 319.562 672.875 319.562z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="organization" unicode="" d="M304 515c35-41 86-67 144-67s109 26 144 67c22-40 64-67 112-67 71 0 128 57 128 128s-57 128-128 128c-26 0-49-8-69-21C615 768 539 832 448 832S281 768 261 683c-20 13-43 21-69 21-71 0-128-57-128-128s57-128 128-128c48 0 90 27 112 67z m333 97c13 24 38 41 67 41 42 0 77-35 77-77s-35-77-77-77-75 34-76 75c4 12 7 25 9 38zM448 769c71 0 129-58 129-129s-58-129-129-129-129 58-129 129S377 769 448 769zM192 499c-42 0-77 35-77 77s35 77 77 77c29 0 54-17 67-41 2-13 5-26 9-38-1-41-34-75-76-75z m640-51H64c-35 0-64-29-64-64v-192c0-35 29-64 64-64v-128c0-35 29-64 64-64h64c35 0 64 29 64 64v64h64v-192c0-35 29-64 64-64h128c35 0 64 29 64 64V64h64v-64c0-35 29-64 64-64h64c35 0 64 29 64 64V128c35 0 64 29 64 64V384c0 35-29 64-64 64zM192 0h-64V192H64V384h128v-384z m448 128h-64V256h-64v-384H384V256h-64v-128h-64V384h384v-256z m192 64h-64v-192h-64V384h128v-192z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="package" unicode="" d="M0 559v-478c0-29 19-54 48-62l416-111c10-3 22-3 32 0l416 111c29 8 48 33 48 62V559c0 29-19 54-48 62L496 732c-10 2-22 2-32 0L48 621c-29-8-48-33-48-62z m448-582L64 79V512l384-103v-432zM64 576l160 43 416-111-160-43L64 576z m832-497L512-23V409l128 35v-156l128 34V478l128 34v-433zM768 542L352 653l128 34 416-111-128-34z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="paintcan" unicode="" d="M384 832C171.923 832 0 660.077 0 448v-64c0-35.346 28.654-64 64-64v-320c0-70.692 143.269-128 320-128s320 57.308 320 128V320c35.346 0 64 28.654 64 64v64C768 660.077 596.077 832 384 832zM576 192v-32c0-17.673-14.327-32-32-32s-32 14.327-32 32v32c0 17.673-14.327 32-32 32s-32-14.327-32-32v-160c0-17.673-14.327-32-32-32s-32 14.327-32 32V160c0 17.673-14.327 32-32 32s-32-14.327-32-32v-32c0-35.346-28.654-64-64-64s-64 28.654-64 64v64c-35.346 0-64 28.654-64 64V371.193C186.382 340.108 279.318 320 384 320s197.618 20.108 256 51.193V256C640 220.654 611.346 192 576 192zM384 384c-107.433 0-199.393 26.474-237.372 64 37.979 37.526 129.939 64 237.372 64s199.393-26.474 237.372-64C583.393 410.474 491.433 384 384 384zM384 576c-176.62 0-319.816-57.236-319.996-127.867-0.001 0.001-0.002 0.001-0.003 0.002C64.075 624.804 207.314 768 384 768c176.731 0 320-143.269 320-320C704 518.692 560.731 576 384 576z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="pencil" unicode="" d="M0 64v-192h192l512 512-192 192L0 64z m192-128H64V64h64v-64h64v-64z m659 595l-83-83-192 192 83 83c25 25 65 25 90 0l102-102c25-25 25-65 0-90z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="person" unicode="" d="M448 448H64c-35 0-64-29-64-64v-320h128v-192c0-35 29-64 64-64h128c35 0 64 29 64 64V64h128V384c0 35-29 64-64 64z m0-320h-64V256h-64v-384H192V256h-64v-128H64V384h384v-256z m0 512C448 746 362 832 256 832S64 746 64 640s86-192 192-192 192 86 192 192zM256 512c-71 0-128 57-128 128S185 768 256 768s128-57 128-128-57-128-128-128z" horiz-adv-x="512" />
|
||||
<glyph glyph-name="pin" unicode="" d="M640 755v-51l32-64-288-192H141c-28 0-43-34-22-55l201-201L64-128l320 256 201-201c21-21 55-6 55 22V192l192 288 64-32h51c28 0 43 34 22 55L695 777c-21 21-55 6-55-22z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="plug" unicode="" d="M960 448v64H704V640H576v-64H448c-66 0-113-52-128-128l-64-64c-106 0-192-86-192-192v-128h64V192c0 71 57 128 128 128l64-64c16-74 63-128 128-128h128v-64h128V192h256v64H704V448h256z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="plus" unicode="" d="M768 256H448v-320H320V256H0V384h320V704h128v-320h320v-128z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="primitive-dot" unicode="" d="M0 320c0 141 115 256 256 256s256-115 256-256-115-256-256-256S0 179 0 320z" horiz-adv-x="512" />
|
||||
<glyph glyph-name="primitive-square" unicode="" d="M512 64H0V576h512V64z" horiz-adv-x="512" />
|
||||
<glyph glyph-name="pulse" unicode="" d="M736 320.062L563.188 486.406 422.406 288 352 729.594 152.438 320.062H0V192h230.406L288 307.188l57.594-345.562L576 288l102.375-96H896V320.062H736z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="question" unicode="" d="M384 192h128v-128H384V192z m256 224c0-137-128-160-128-160H384c0 35 29 64 64 64h32c18 0 32 14 32 32v64c0 18-14 32-32 32h-64c-18 0-32-14-32-32v-32H256c0 96 96 192 192 192s192-64 192-160zM448 685c201 0 365-164 365-365S649-45 448-45 83 119 83 320s164 365 365 365m0 83C201 768 0 567 0 320s201-448 448-448 448 201 448 448S695 768 448 768z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="quote" unicode="" d="M394 629C239 529 163 426 163 254c10 3 19 3 28 3 81 0 160-55 160-154 0-103-66-167-160-167C70-64 0 33 0 208 0 451 112 626 321 747l73-118z m448 0C687 529 611 426 611 254c10 3 19 3 28 3 81 0 160-55 160-154 0-103-66-167-160-167-121 0-191 97-191 272 0 243 112 418 321 539l73-118z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="radio-tower" unicode="" d="M306.838 441.261c15.868 16.306 15.868 42.731 0 59.037-20.521 21.116-30.643 48.417-30.705 76.124 0.062 27.77 10.183 55.039 30.705 76.186 15.868 16.337 15.868 42.764 0 59.069-7.934 8.184-18.272 12.275-28.706 12.275-10.371 0-20.804-4.029-28.738-12.213-36.266-37.297-54.633-86.433-54.57-135.317-0.062-48.792 18.305-97.927 54.57-135.161C265.262 424.955 290.97 424.955 306.838 441.261zM149.093 798.858c-8.121 8.309-18.68 12.463-29.3 12.463-10.558 0-21.179-4.154-29.237-12.463C30.8 737.509 0.751 656.856 0.813 576.422 0.751 496.081 30.8 415.272 90.494 353.985c16.181-16.618 42.356-16.618 58.537 0 16.118 16.587 16.118 43.513 0 60.067-43.7 44.98-65.44 103.456-65.44 162.368s21.74 117.449 65.44 162.368C165.149 755.439 165.149 782.365 149.093 798.858zM513.031 472.153c57.351 0 103.956 46.574 103.956 103.956 0 57.382-46.605 103.955-103.956 103.955-57.381 0-103.956-46.573-103.956-103.955C409.076 518.727 455.65 472.153 513.031 472.153zM933.539 798.233c-16.181 16.618-42.355 16.618-58.475 0-16.181-16.587-16.181-43.513 0-60.068 43.668-44.918 65.409-103.456 65.409-162.368 0-58.85-21.805-117.387-65.473-162.306-16.117-16.618-16.117-43.575 0.062-60.068 8.059-8.309 18.616-12.463 29.237-12.463 10.558 0 21.178 4.154 29.236 12.463 59.726 61.287 89.774 142.096 89.649 222.437C1023.313 656.138 993.264 736.947 933.539 798.233zM513.281 389.127L513.281 389.127c-26.489-0.062-53.04 6.466-77.091 19.429L235.057-127.59000000000003h95.209l54.819 63.973h255.891l53.977-63.973h95.272L589.124 408.431C565.384 395.655 539.395 389.127 513.281 389.127zM512.656 358.483L577.004 128.29999999999995H449.059L512.656 358.483zM385.086 0.3550000000000182l63.974 63.973h127.944l63.974-63.973H385.086zM717.194 710.958c-15.868-16.306-15.868-42.731 0-59.037 20.491-21.116 30.611-48.511 30.674-76.124-0.062-27.77-10.183-55.102-30.674-76.187-15.868-16.336-15.868-42.763 0-59.068 7.871-8.184 18.242-12.213 28.737-12.213 10.309 0 20.741 4.029 28.675 12.213 36.298 37.234 54.665 86.433 54.54 135.255 0.125 48.792-18.181 97.927-54.54 135.161C758.801 727.264 733.062 727.264 717.194 710.958z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="repo" unicode="" d="M256 256h-64v64h64v-64z m0 192h-64v-64h64v64z m0 128h-64v-64h64v64z m0 128h-64v-64h64v64z m512 64v-768c0-35-29-64-64-64H384v-128l-96 96-96-96V-64H64c-35 0-64 29-64 64V768C0 803 29 832 64 832h640c35 0 64-29 64-64z m-64-640H64v-128h128v64h192v-64h320V128z m0 640H128v-576h576V768z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="repo-clone" unicode="" d="M960 832H576v-448c0-35 29-64 64-64h64v-64h64v64h192c35 0 64 29 64 64V768c0 35-29 64-64 64zM704 384h-64v64h64v-64z m256 0H768v64h192v-64z m0 128H704V768h256v-256z m-704 0h-64v64h64v-64z m0 128h-64v64h64v-64zM128 768h384V832H64C29 832 0 803 0 768v-768c0-35 29-64 64-64h128v-128l96 96 96-96V-64h320c35 0 64 29 64 64V192H128V768z m576-640v-128H384v64H192v-64H64V128h640zM192 320h64v-64h-64v64z m64 64h-64v64h64v-64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="repo-force-push" unicode="" d="M640 256H512v-448H384V256H256l144 192H256l192 256 192-256H496l144-192zM704 832H64C29 832 0 803 0 768v-768c0-35 29-64 64-64h256v64H64V128h256v64H128V768h576v-576H576v-64h128v-128H576v-64h128c35 0 64 29 64 64V768c0 35-29 64-64 64z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="repo-forked" unicode="" d="M512 768c-71 0-128-57-128-128 0-47 26-88 64-110v-82L320 320 192 448v82c38 22 64 63 64 110 0 71-57 128-128 128S0 711 0 640c0-47 26-88 64-110v-114l192-192v-114c-38-22-64-63-64-110 0-71 57-128 128-128s128 57 128 128c0 47-26 88-64 110V224l192 192V530c38 22 64 63 64 110 0 71-57 128-128 128zM128 563c-42 0-77 35-77 77s35 77 77 77 77-35 77-77-35-77-77-77z m192-640c-42 0-77 35-77 77s35 77 77 77 77-35 77-77-35-77-77-77z m192 640c-42 0-77 35-77 77s35 77 77 77 77-35 77-77-35-77-77-77z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="repo-pull" unicode="" d="M832 320V448H448V576h384V704l192-192-192-192zM256 704h-64v-64h64v64z m448-320h64v-384c0-35-29-64-64-64H384v-128l-96 96-96-96V-64H64c-35 0-64 29-64 64V768C0 803 29 832 64 832h640c35 0 64-29 64-64v-128h-64V768H128v-576h576V384z m0-256H64v-128h128v64h192v-64h320V128zM256 448h-64v-64h64v64z m0 128h-64v-64h64v64z m-64-320h64v64h-64v-64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="repo-push" unicode="" d="M256 640h-64v64h64v-64z m-64-128h64v64h-64v-64z m256 0L256 256h128v-448h128V256h128L448 512zM704 832H64C29 832 0 803 0 768v-768c0-35 29-64 64-64h256v64H64V128h256v64H128V768h577l-1-576H576v-64h128v-128H576v-64h128c35 0 64 29 64 64V768c0 35-29 64-64 64z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="rocket" unicode="" d="M1024 832s-6-24-19-68c-13-45-35-101-68-170-45 5-81 21-106 46s-40 60-45 105c69 33 125 56 169 69 45 13 69 18 69 18zM779 587c-17 17-30 35-40 56-10 20-17 42-22 65-37-21-74-45-111-72-37-28-73-60-108-95-45-45-85-116-114-157H192L0 192h192l128 128c-22-49-65-191-64-192l64-64c1-1 143 41 192 64L384 0v-192l192 192V192c41 29 112 70 157 114 35 35 67 72 94 109 28 37 52 74 73 110-23 5-45 12-66 22-20 10-38 23-55 40z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="rss" unicode="" d="M128 0H0V128c71 0 128-57 128-128zM0 640v-64c318 0 576-258 576-576h64c0 353-287 640-640 640z m0-256v-64c176 0 320-144 320-320h64c0 212-172 384-384 384z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="ruby" unicode="" d="M832 448L512 128V576h192l128-128z m192 0L512-64 0 448l256 256h512l256-256zM512 32l416 416-192 192H288L96 448l416-416z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="search" unicode="" d="M1005-83L761 162c45 63 71 139 71 222 0 212-172 384-384 384S64 596 64 384s172-384 384-384c83 0 159 26 222 71l245-244c12-13 29-19 45-19s33 6 45 19c25 25 25 65 0 90zM448 83c-166 0-301 135-301 301s135 301 301 301 301-135 301-301-135-301-301-301z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="server" unicode="" d="M704 448H64c-35 0-64-29-64-64v-128c0-35 29-64 64-64h640c35 0 64 29 64 64V384c0 35-29 64-64 64zM128 256H64V384h64v-128z m128 0h-64V384h64v-128z m128 0h-64V384h64v-128z m128 0h-64V384h64v-128zM704 768H64C29 768 0 739 0 704v-128c0-35 29-64 64-64h640c35 0 64 29 64 64V704c0 35-29 64-64 64zM128 576H64V704h64v-128z m128 0h-64V704h64v-128z m128 0h-64V704h64v-128z m128 0h-64V704h64v-128z m192 64h-64v64h64v-64z m0-512H64c-35 0-64-29-64-64v-128c0-35 29-64 64-64h640c35 0 64 29 64 64V64c0 35-29 64-64 64zM128-64H64V64h64v-128z m128 0h-64V64h64v-128z m128 0h-64V64h64v-128z m128 0h-64V64h64v-128z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="settings" unicode="" d="M192 384h-64V704h64v-320z m-64-448h64V128h-64v-192z m320 0h64V320h-64v-384z m320 0h64V64h-64v-128z m64 768h-64v-384h64V704z m-320 0h-64v-128h64V704zM256 320H64c-35 0-64-29-64-64s29-64 64-64h192c35 0 64 29 64 64s-29 64-64 64z m320 192H384c-35 0-64-29-64-64s29-64 64-64h192c35 0 64 29 64 64s-29 64-64 64z m320-256H704c-35 0-64-29-64-64s29-64 64-64h192c35 0 64 29 64 64s-29 64-64 64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="shield" unicode="" d="M448 832L0 704v-385c0-299 340-511 448-511s448 212 448 511V704L448 832zM320 128l73 179c3 15-4 30-16 38-36 23-57 61-57 103 0 70 57 128 127 128 69 0 129-58 129-128 0-42-21-80-57-103-12-8-19-23-16-38l73-179H320z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="sign-in" unicode="" d="M384 400v-336h256V320h64v-256c0-35-29-64-64-64H384v-192L35-18c-21 11-35 33-35 58V768C0 803 29 832 64 832h576c35 0 64-29 64-64v-192h-64V768H128l256-128v-144l192 144v-128h256v-128H576v-128L384 400z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="sign-out" unicode="" d="M768 256V384H512V512h256V640l256-192-256-192zM640 64H384V640L128 768h512v-192h64V768c0 35-29 64-64 64H64C29 832 0 803 0 768v-728c0-25 14-47 35-58l349-174V0h256c35 0 64 29 64 64V320h-64v-256z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="smiley" unicode="" d="M512 832C229 832 0 603 0 320s229-512 512-512 512 229 512 512S795 832 512 832z m308-820c-40-40-87-71-139-93-53-23-110-34-169-34s-116 11-169 34c-52 22-99 53-139 93s-71 87-93 139c-23 53-34 110-34 169s11 116 34 169c22 52 53 99 93 139s87 71 139 93c53 23 110 34 169 34s116-11 169-34c52-22 99-53 139-93s71-87 93-139c23-53 34-110 34-169s-11-116-34-169c-22-52-53-99-93-139zM256 461v38c0 42 34 76 77 76h38c42 0 76-34 76-76v-38c0-43-34-77-76-77h-38c-43 0-77 34-77 77z m320 0v38c0 42 34 76 77 76h38c42 0 76-34 76-76v-38c0-43-34-77-76-77h-38c-43 0-77 34-77 77z m256-269c-46-120-186-192-320-192s-274 72-320 192c-9 25 15 64 42 64h550c26 0 57-39 48-64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="squirrel" unicode="" d="M768 768c-141.385 0-256-83.75-256-186.875C512 457.25 544 387 512 192c0 288-177 405.783-256 405.783 3.266 32.17-30.955 42.217-30.955 42.217s-14-7.124-19.354-21.583c-17.231 20.053-36.154 17.54-36.154 17.54l-8.491-37.081c0 0-117.045-40.876-118.635-206.292C56 371 141.311 353.898 201.887 364.882c57.157-2.956 42.991-50.648 30.193-63.446C178.083 247.438 128 320 64 320s-64-64 0-64 64-64 192-64c-198-77 0-256 0-256h-64c-64 0-64-64-64-64s256 0 384 0c192 0 320 64 320 222.182 0 54.34-27.699 114.629-64 162.228C697.057 349.433 782.453 427.566 832 384s192-64 192 128C1024 653.385 909.385 768 768 768zM160 448c-17.674 0-32 14.327-32 32 0 17.674 14.326 32 32 32 17.673 0 32-14.326 32-32C192 462.327 177.673 448 160 448z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="star" unicode="" d="M896 448l-313.5 40.781L448 768 313.469 488.781 0 448l230.469-208.875L171-63.93799999999999l277 148.812 277.062-148.812L665.5 239.125 896 448z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="stop" unicode="" d="M640 768H256L0 512v-384l256-256h384l256 256V512L640 768z m192-608L608-64H288L64 160V480l224 224h320l224-224v-320zM384 576h128v-320H384V576z m0-384h128v-128H384V192z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="sync" unicode="" d="M655.461 358.531c11.875-81.719-13.062-167.781-76.812-230.594-94.188-92.938-239.5-104.375-346.375-34.562l74.875 73L31.96 204.75 70.367-64l84.031 80.5c150.907-111.25 364.938-100.75 502.063 34.562 79.5 78.438 115.75 182.562 111.25 285.312L655.461 358.531zM189.46 511.938c94.156 92.938 239.438 104.438 346.313 34.562l-75-72.969 275.188-38.406L697.586 704l-83.938-80.688C462.711 734.656 248.742 724.031 111.585 588.75 32.085 510.344-4.133 406.219 0.335 303.5l112.25-22.125C100.71 363.125 125.71 449.094 189.46 511.938z" horiz-adv-x="768.051" />
|
||||
<glyph glyph-name="tag" unicode="" d="M431 657c-30 30-71 47-113 47H160C72 704 0 632 0 544v-158c0-42 17-83 47-113l388-388c25-25 65-25 90 0l294 294c25 25 25 65 0 90L431 657zM88 314c-20 19-30 45-30 72V544c0 56 46 102 102 102h158c27 0 53-10 72-30l393-392-303-303L88 314z m40 262h128v-128H128V576z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="tasklist" unicode="" d="M986 256H486c-38 0-38 26-38 64s0 64 38 64h500c38 0 38-26 38-64s0-64-38-64zM614 576c-38 0-38 26-38 64s0 64 38 64h372c38 0 38-26 38-64s0-64-38-64H614zM0 582l90 83 102-102L454 832l90-90-352-352L0 582z m486-518h500c38 0 38-26 38-64s0-64-38-64H486c-38 0-38 26-38 64s0 64 38 64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="telescope" unicode="" d="M512 256l192-384h-64L512 128v-320h-64V192L320-128h-64l128 320 128 64zM448 832h-64v-64h64V832zM320 640h-64v-64h64v64zM128 768H64v-64h64V768zM40 256c-14-10-18-28-10-43l35-59c8-15 26-20 41-13l89 42-74 128-81-55z m505 345L174 348l79-137 405 194-113 196z m270-82l-94 161c-9 16-30 21-46 11l-77-53 118-205 85 41c17 8 23 28 14 45z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="terminal" unicode="" d="M448 192h256v-64H448v64z m-192-64l192 192-192 192-48-48 144-144-144-144 48-48z m640 512v-640c0-35-29-64-64-64H64c-35 0-64 29-64 64V640c0 35 29 64 64 64h768c35 0 64-29 64-64z m-64 0H64v-640h768V640z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="text-size" unicode="" d="M1150-64h-144l-61 208H685l-61-208H480l-44 149H226l-45-149H42l211 614h160l139-406 185 560h161l252-768zM407 184s-65 231-75 263h-5l-72-263h152z m507 67l-97 347h-4l-96-347h197z" horiz-adv-x="1152" />
|
||||
<glyph glyph-name="three-bars" unicode="" d="M730 256H38c-38 0-38 26-38 64s0 64 38 64h692c38 0 38-26 38-64s0-64-38-64z m0 256H38c-38 0-38 26-38 64s0 64 38 64h692c38 0 38-26 38-64s0-64-38-64zM38 128h692c38 0 38-26 38-64s0-64-38-64H38c-38 0-38 26-38 64s0 64 38 64z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="thumbsdown" unicode="" d="M1023 331l-62 381C950 800 840 832 768 832H364c-13 0-24-3-34-9l-92-55H128C60 768 0 708 0 640v-256c0-68 60-129 128-128h128c58 0 89-29 153-99 58-64 56-115 40-209-5-32 4-64 27-91 25-30 63-49 100-49 117 0 192 238 192 321l-1 63c1 0 1 0 1 0h129c74 0 125 51 127 126 0 4 1 8-1 13z m-126-76H769c-45 0-66-18-66-62l2-66c0-81-75-256-128-256-32 0-69 32-64 64 16 101 22 178-57 265-65 72-113 120-200 120V704l107 64h405c47 0 125-20 128-64l1-1 64-384c-2-41-24-64-64-64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="thumbsup" unicode="" d="M896 448H768s0 0-1 0l1 63c0 83-75 321-192 321-37 0-75-19-100-49-23-26-32-58-27-90 16-95 18-146-40-210-64-70-95-99-153-99H128C60 384 0 324 0 256v-256c0-68 60-128 128-128h110l92-55c10-6 21-9 33-9h405c72 0 182 32 192 120l63 381c1 5 1 9 1 13-2 75-54 126-128 126z m0-512c-3-44-81-64-128-64H363l-107 64V320c87 0 135 48 200 120 79 87 73 164 56 264-5 32 32 64 64 64 53 0 128-175 128-256l-1-66c0-44 21-62 65-62h128c40 0 63-23 64-64l-64-384z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="tools" unicode="" d="M286.547 366.984c16.843-16.812 81.716-85.279 81.716-85.279l35.968 37.093-56.373 58.248L456.072 491.98c0 0-48.842 47.623-27.468 28.655 20.438 75.903 1.812 160.589-55.842 220.243C315.608 800.064 234.392 819.47 161.425 799.096l123.653-127.715-32.53-125.309-121.06-33.438L7.898 640.3820000000001c-19.718-75.436-0.969-159.339 56.311-218.556C124.302 359.703 210.83 341.453 286.547 366.984zM698.815 242.769L549.694 95.46100000000001l245.932-254.805c20.062-20.812 46.498-31.188 72.872-31.188 26.25 0 52.624 10.375 72.811 31.188 40.249 41.624 40.249 108.997 0 150.62L698.815 242.769zM1023.681 670.162L867.06 832.001 405.387 354.703l56.373-58.248L185.425 10.839000000000055l-63.154-33.749-89.217-145.559 22.719-23.562 140.839 92.247 32.655 65.312 276.336 285.554 56.404-58.248L1023.681 670.162z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="trashcan" unicode="" d="M640 704H512c0 35-29 64-64 64H256c-35 0-64-29-64-64H64c-35 0-64-29-64-64v-64c0-35 29-64 64-64v-576c0-35 29-64 64-64h448c35 0 64 29 64 64V512c35 0 64 29 64 64v64c0 35-29 64-64 64z m-64-768H128V512h64v-512h64V512h64v-512h64V512h64v-512h64V512h64v-576z m64 640H64v64h576v-64z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="triangle-down" unicode="" d="M0 512l384-384 384 384H0z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="triangle-left" unicode="" d="M384 704L0 320l384-384V704z" horiz-adv-x="384" />
|
||||
<glyph glyph-name="triangle-right" unicode="" d="M0-64l384 384L0 704v-768z" horiz-adv-x="384" />
|
||||
<glyph glyph-name="triangle-up" unicode="" d="M768 128L384 512 0 128h768z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="unfold" unicode="" d="M736 288l160-160c0-35-29-64-64-64H576v64h224L672 256H224L96 128h224v-64H64c-35 0-64 29-64 64l160 160L0 448c0 35 29 64 64 64h256v-64H96l128-128h448l128 128H576v64h256c35 0 64-29 64-64L736 288z m-352 96h128V576h128L448 768 256 576h128v-192z m128-192H384v-192H256l192-192 192 192H512V192z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="unmute" unicode="" d="M704 319c0-70-29-134-75-181l-43 43c35 36 57 84 57 138s-22 103-57 138l43 43c46-46 75-110 75-181zM430 686L192 448H64c-35 0-64-29-64-64v-128c0-35 29-64 64-64h128l238-238c30-30 82-9 82 34V652c0 43-52 64-82 34z m380-5l-43-43c82-82 132-194 132-319 0-124-50-237-132-319l43-43c93 93 150 221 150 362 0 142-57 270-150 362z m-90-90l-44-43c59-59 95-140 95-229s-36-170-95-228l44-43c69 69 112 165 112 271s-43 202-112 272z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="unverified" unicode="" d="M1003 380l-69 86c-11 14-18 31-20 49l-12 109c-5 45-40 80-85 85l-109 12c-19 2-36 10-50 21l-86 69c-35 28-85 28-120 0l-86-69c-14-11-31-18-49-20l-109-12c-45-5-80-40-85-85l-12-109c-2-19-10-36-21-50l-69-86c-28-35-28-85 0-120l69-86c11-14 18-31 20-49l12-109c5-45 40-80 85-85l109-12c19-2 36-10 50-21l86-69c35-28 85-28 120 0l86 69c14 11 31 18 49 20l109 12c45 5 80 40 85 85l12 109c2 19 10 36 21 50l69 86c28 35 28 85 0 120zM576 96c0-18-14-32-32-32h-64c-17 0-32 14-32 32v64c0 18 15 32 32 32h64c18 0 32-14 32-32v-64z m100 313c-4-11-11-21-19-30-8-10-9-12-21-24-10-11-20-19-33-29-7-6-13-12-18-17s-9-11-12-17-5-12-7-19-2-8-2-16H456c0 14 0 20 2 31 2 12 5 23 9 33 4 9 9 18 16 27 7 8 15 16 26 24 17 12 23 19 31 33s13 24 13 38c0 17-4 29-13 37-8 8-20 12-37 12-6 0-12-1-19-3s-11-6-16-10-9-7-13-13-6-9-6-18H321c0 24 8 36 17 53 10 17 23 32 39 43s35 19 56 24 45 8 70 8c28 0 53-3 75-8 22-6 40-14 56-25 15-11 26-24 35-40 8-16 12-35 12-56 0-14 0-27-5-38z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="verified" unicode="" d="M1003 380l-69 86c-11 14-18 31-20 49l-12 109c-5 45-40 80-85 85l-109 12c-19 2-36 10-50 21l-86 69c-35 28-85 28-120 0l-86-69c-14-11-31-18-49-20l-109-12c-45-5-80-40-85-85l-12-109c-2-19-10-36-21-50l-69-86c-28-35-28-85 0-120l69-86c11-14 18-31 20-49l12-109c5-45 40-80 85-85l109-12c19-2 36-10 50-21l86-69c35-28 85-28 120 0l86 69c14 11 31 18 49 20l109 12c45 5 80 40 85 85l12 109c2 19 10 36 21 50l69 86c28 35 28 85 0 120zM416 64L192 288l96 96 128-128 320 320 96-99-416-413z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="versions" unicode="" d="M832 640H448c-35 0-64-29-64-64v-512c0-35 29-64 64-64h384c35 0 64 29 64 64V576c0 35-29 64-64 64z m-64-512H512V512h256v-384zM256 576h64v-64h-64v-384h64v-64h-64c-35 0-64 29-64 64V512c0 35 29 64 64 64zM64 512h64v-64H64v-256h64v-64H64c-35 0-64 29-64 64V448c0 35 29 64 64 64z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="watch" unicode="" d="M384 320h128v-64H320V512h64v-192z m384 0c0-142-77-266-192-332v-116c0-35-29-64-64-64H256c-35 0-64 29-64 64V-12C77 54 0 178 0 320s77 266 192 332V768c0 35 29 64 64 64h256c35 0 64-29 64-64v-116c115-66 192-190 192-332z m-64 0c0 177-143 320-320 320S64 497 64 320s143-320 320-320 320 143 320 320z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="x" unicode="" d="M479 320l240-240-95-95-240 240-240-240-95 95 240 240L49 560l95 95 240-240 240 240 95-95-240-240z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="zap" unicode="⚡" d="M640 384H384L576 832 0 256h256L64-192 640 384z" horiz-adv-x="640" />
|
||||
</font>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 66 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user