feat: sync langpack and auth updates
Sync telesrv commits 49f9bab and 04d9563 into the public mirror. Exclude private docs and runtime key material per sync rules.
This commit is contained in:
parent
6af61f26ba
commit
1292540350
244 changed files with 1552172 additions and 27668 deletions
|
|
@ -5,14 +5,20 @@
|
|||
// 用法:
|
||||
//
|
||||
// langpackfetch languages [pack] 列出某 pack(默认 android)的可用语言
|
||||
// langpackfetch all <out_dir> [pack...] 拉取所有官方语言及 manifest
|
||||
// langpackfetch <out_dir> <langCode> [pack...] 拉取语言包(默认 packs = android ios macos)
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -26,13 +32,46 @@ const (
|
|||
tdesktopAPIHash = "344583e45741c457fe1862106095a5eb"
|
||||
)
|
||||
|
||||
var (
|
||||
officialPacks = []string{"android", "android_x", "ios", "macos", "tdesktop", "weba", "webk"}
|
||||
packNameRE = regexp.MustCompile(`^[a-z0-9][a-z0-9_-]{0,31}$`)
|
||||
langCodeRE = regexp.MustCompile(`^[a-z0-9]{1,16}(?:[-_][a-z0-9]{1,16})*$`)
|
||||
)
|
||||
|
||||
type manifest struct {
|
||||
Schema int `json:"schema"`
|
||||
Packs []packManifest `json:"packs"`
|
||||
}
|
||||
|
||||
type packManifest struct {
|
||||
Name string `json:"name"`
|
||||
Languages []languageManifest `json:"languages"`
|
||||
}
|
||||
|
||||
type languageManifest struct {
|
||||
LangCode string `json:"lang_code"`
|
||||
Name string `json:"name"`
|
||||
NativeName string `json:"native_name"`
|
||||
BaseLangCode string `json:"base_lang_code,omitempty"`
|
||||
PluralCode string `json:"plural_code"`
|
||||
Official bool `json:"official"`
|
||||
RTL bool `json:"rtl,omitempty"`
|
||||
Beta bool `json:"beta,omitempty"`
|
||||
StringsCount int `json:"strings_count"`
|
||||
TranslatedCount int `json:"translated_count"`
|
||||
TranslationsURL string `json:"translations_url,omitempty"`
|
||||
Version int `json:"version"`
|
||||
File string `json:"file"`
|
||||
SHA256 string `json:"sha256"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Fprintln(os.Stderr, "usage:\n langpackfetch languages [pack]\n langpackfetch <out_dir> <langCode> [pack...]")
|
||||
fmt.Fprintln(os.Stderr, "usage:\n langpackfetch languages [pack]\n langpackfetch all <out_dir> [pack...]\n langpackfetch <out_dir> <langCode> [pack...]")
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 6*time.Minute)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
client := telegram.NewClient(tdesktopAPIID, tdesktopAPIHash, telegram.Options{})
|
||||
|
|
@ -55,6 +94,16 @@ func main() {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
if os.Args[1] == "all" {
|
||||
if len(os.Args) < 3 {
|
||||
return fmt.Errorf("all needs <out_dir>")
|
||||
}
|
||||
packs := os.Args[3:]
|
||||
if len(packs) == 0 {
|
||||
packs = officialPacks
|
||||
}
|
||||
return fetchAll(ctx, api, os.Args[2], packs)
|
||||
}
|
||||
|
||||
outRoot := os.Args[1]
|
||||
langCode := "en"
|
||||
|
|
@ -74,7 +123,7 @@ func main() {
|
|||
fmt.Fprintf(os.Stderr, "skip %s/%s: %v\n", pack, langCode, err)
|
||||
continue
|
||||
}
|
||||
if err := writePack(outRoot, pack, diff); err != nil {
|
||||
if _, err := writePack(outRoot, pack, diff); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -85,10 +134,88 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
func writePack(root, pack string, diff *tg.LangPackDifference) error {
|
||||
func fetchAll(ctx context.Context, api *tg.Client, root string, packs []string) error {
|
||||
seen := make(map[string]struct{}, len(packs))
|
||||
result := manifest{Schema: 1}
|
||||
for _, pack := range packs {
|
||||
pack = strings.ToLower(strings.TrimSpace(pack))
|
||||
if !packNameRE.MatchString(pack) {
|
||||
return fmt.Errorf("invalid lang pack %q", pack)
|
||||
}
|
||||
if _, ok := seen[pack]; ok {
|
||||
continue
|
||||
}
|
||||
seen[pack] = struct{}{}
|
||||
|
||||
languages, err := api.LangpackGetLanguages(ctx, pack)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getLanguages %q: %w", pack, err)
|
||||
}
|
||||
sort.Slice(languages, func(i, j int) bool { return languages[i].LangCode < languages[j].LangCode })
|
||||
pm := packManifest{Name: pack}
|
||||
for _, language := range languages {
|
||||
if !language.Official {
|
||||
continue
|
||||
}
|
||||
code := strings.ToLower(strings.TrimSpace(language.LangCode))
|
||||
if !langCodeRE.MatchString(code) {
|
||||
return fmt.Errorf("invalid language code %q returned for %q", language.LangCode, pack)
|
||||
}
|
||||
diff, err := api.LangpackGetLangPack(ctx, &tg.LangpackGetLangPackRequest{
|
||||
LangPack: pack,
|
||||
LangCode: code,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("getLangPack %s/%s: %w", pack, code, err)
|
||||
}
|
||||
written, err := writePack(root, pack, diff)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rel, err := filepath.Rel(root, written.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pm.Languages = append(pm.Languages, languageManifest{
|
||||
LangCode: code,
|
||||
Name: language.Name,
|
||||
NativeName: language.NativeName,
|
||||
BaseLangCode: language.BaseLangCode,
|
||||
PluralCode: language.PluralCode,
|
||||
Official: language.Official,
|
||||
RTL: language.Rtl,
|
||||
Beta: language.Beta,
|
||||
StringsCount: language.StringsCount,
|
||||
TranslatedCount: language.TranslatedCount,
|
||||
TranslationsURL: language.TranslationsURL,
|
||||
Version: diff.Version,
|
||||
File: filepath.ToSlash(rel),
|
||||
SHA256: written.SHA256,
|
||||
})
|
||||
}
|
||||
fmt.Printf("pack %s complete: %d official languages\n", pack, len(pm.Languages))
|
||||
result.Packs = append(result.Packs, pm)
|
||||
}
|
||||
encoded, err := json.MarshalIndent(result, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return writeFileAtomic(filepath.Join(root, "official-language-packs.json"), append(encoded, '\n'))
|
||||
}
|
||||
|
||||
type writtenPack struct {
|
||||
Path string
|
||||
SHA256 string
|
||||
}
|
||||
|
||||
func writePack(root, pack string, diff *tg.LangPackDifference) (writtenPack, error) {
|
||||
pack = strings.ToLower(strings.TrimSpace(pack))
|
||||
if !packNameRE.MatchString(pack) {
|
||||
return writtenPack{}, fmt.Errorf("invalid lang pack %q", pack)
|
||||
}
|
||||
dir := filepath.Join(root, pack)
|
||||
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||||
return err
|
||||
return writtenPack{}, err
|
||||
}
|
||||
var b strings.Builder
|
||||
count := 0
|
||||
|
|
@ -116,13 +243,51 @@ func writePack(root, pack string, diff *tg.LangPackDifference) error {
|
|||
}
|
||||
langCode := diff.LangCode
|
||||
if langCode == "" {
|
||||
langCode = "unknown"
|
||||
return writtenPack{}, fmt.Errorf("empty language code returned for %q", pack)
|
||||
}
|
||||
langCode = strings.ToLower(langCode)
|
||||
if !langCodeRE.MatchString(langCode) {
|
||||
return writtenPack{}, fmt.Errorf("invalid language code %q returned for %q", diff.LangCode, pack)
|
||||
}
|
||||
name := fmt.Sprintf("%s_%s_v%d.strings", pack, langCode, diff.Version)
|
||||
path := filepath.Join(dir, name)
|
||||
if err := os.WriteFile(path, []byte(b.String()), 0o644); err != nil {
|
||||
data := []byte(b.String())
|
||||
if err := writeFileAtomic(path, data); err != nil {
|
||||
return writtenPack{}, err
|
||||
}
|
||||
sum := sha256.Sum256(data)
|
||||
fmt.Printf("wrote %s (%d strings, version %d)\n", path, count, diff.Version)
|
||||
return writtenPack{Path: path, SHA256: hex.EncodeToString(sum[:])}, nil
|
||||
}
|
||||
|
||||
func writeFileAtomic(path string, data []byte) error {
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("wrote %s (%d strings, version %d)\n", path, count, diff.Version)
|
||||
tmp, err := os.CreateTemp(filepath.Dir(path), ".langpack-*.tmp")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tmpName := tmp.Name()
|
||||
defer os.Remove(tmpName)
|
||||
if err := tmp.Chmod(0o644); err != nil {
|
||||
_ = tmp.Close()
|
||||
return err
|
||||
}
|
||||
if _, err := tmp.Write(data); err != nil {
|
||||
_ = tmp.Close()
|
||||
return err
|
||||
}
|
||||
if err := tmp.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Rename(tmpName, path); err != nil {
|
||||
if removeErr := os.Remove(path); removeErr != nil && !os.IsNotExist(removeErr) {
|
||||
return fmt.Errorf("replace %q: %w (remove existing: %v)", path, err, removeErr)
|
||||
}
|
||||
if err := os.Rename(tmpName, path); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
78
cmd/langpackfetch/main_test.go
Normal file
78
cmd/langpackfetch/main_test.go
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/iamxvbaba/td/tg"
|
||||
)
|
||||
|
||||
func TestWritePack(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
diff := &tg.LangPackDifference{
|
||||
LangCode: "pt-br",
|
||||
Version: 42,
|
||||
Strings: []tg.LangPackStringClass{
|
||||
&tg.LangPackString{Key: "plain", Value: "value"},
|
||||
&tg.LangPackStringPluralized{Key: "items", OneValue: "one", OtherValue: "many"},
|
||||
&tg.LangPackStringDeleted{Key: "removed"},
|
||||
},
|
||||
}
|
||||
written, err := writePack(root, "tdesktop", diff)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
wantPath := filepath.Join(root, "tdesktop", "tdesktop_pt-br_v42.strings")
|
||||
if written.Path != wantPath {
|
||||
t.Fatalf("path = %q, want %q", written.Path, wantPath)
|
||||
}
|
||||
data, err := os.ReadFile(wantPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
text := string(data)
|
||||
for _, want := range []string{`"plain" = "value";`, `"items#one" = "one";`, `"items#other" = "many";`} {
|
||||
if !strings.Contains(text, want) {
|
||||
t.Errorf("output does not contain %q: %s", want, text)
|
||||
}
|
||||
}
|
||||
if strings.Contains(text, "removed") {
|
||||
t.Errorf("deleted key was emitted: %s", text)
|
||||
}
|
||||
sum := sha256.Sum256(data)
|
||||
if written.SHA256 != hex.EncodeToString(sum[:]) {
|
||||
t.Fatalf("sha256 = %q, want %x", written.SHA256, sum)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWritePackRejectsPathComponents(t *testing.T) {
|
||||
_, err := writePack(t.TempDir(), "../android", &tg.LangPackDifference{LangCode: "en", Version: 1})
|
||||
if err == nil {
|
||||
t.Fatal("expected invalid pack error")
|
||||
}
|
||||
_, err = writePack(t.TempDir(), "android", &tg.LangPackDifference{LangCode: "../en", Version: 1})
|
||||
if err == nil {
|
||||
t.Fatal("expected invalid language code error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteFileAtomicReplacesExisting(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "manifest.json")
|
||||
if err := writeFileAtomic(path, []byte("first")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := writeFileAtomic(path, []byte("second")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(data) != "second" {
|
||||
t.Fatalf("content = %q, want second", data)
|
||||
}
|
||||
}
|
||||
14222
data/langpack/android/android_ar_v59981214.strings
Normal file
14222
data/langpack/android/android_ar_v59981214.strings
Normal file
File diff suppressed because it is too large
Load diff
13227
data/langpack/android/android_be_v59969518.strings
Normal file
13227
data/langpack/android/android_be_v59969518.strings
Normal file
File diff suppressed because it is too large
Load diff
11881
data/langpack/android/android_ca_v59967427.strings
Normal file
11881
data/langpack/android/android_ca_v59967427.strings
Normal file
File diff suppressed because it is too large
Load diff
13305
data/langpack/android/android_cs_v59969803.strings
Normal file
13305
data/langpack/android/android_cs_v59969803.strings
Normal file
File diff suppressed because it is too large
Load diff
11883
data/langpack/android/android_de_v59926882.strings
Normal file
11883
data/langpack/android/android_de_v59926882.strings
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -2040,7 +2040,7 @@
|
|||
"BusinessBotNoAddedText" = "You haven’t added a bot to manage your account. Leave anyway?";
|
||||
"BusinessBotNoAddedTitle" = "No Bot Added";
|
||||
"BusinessBotNotFound" = "Chatbot not found";
|
||||
"BusinessBotNotSupportedMessage" = "This bot doesn’t support **Telegram Business** yet.";
|
||||
"BusinessBotNotSupportedMessage" = "This bot doesn’t support **Secretary Mode** yet.";
|
||||
"BusinessBotNotSupportedTitle" = "Oops";
|
||||
"BusinessBotPermissions" = "Bot permissions";
|
||||
"BusinessBotPermissionsGiftsSection" = "Manage Gifts and Stars";
|
||||
|
|
@ -11646,10 +11646,3 @@
|
|||
"messages#one" = "%1$d message";
|
||||
"messages#other" = "%1$d messages";
|
||||
"telegram_passport" = "Telegram Passport";
|
||||
"FilterByUser" = "Filter by user";
|
||||
"Gift" = "Gift";
|
||||
"GiftDiscount" = "-%1$d%";
|
||||
"Giveaway" = "Giveaway";
|
||||
"Password" = "Password";
|
||||
"Previous" = "Previous";
|
||||
"Volume" = "Volume";
|
||||
11883
data/langpack/android/android_es_v59946392.strings
Normal file
11883
data/langpack/android/android_es_v59946392.strings
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
11531
data/langpack/android/android_fa_v59921144.strings
Normal file
11531
data/langpack/android/android_fa_v59921144.strings
Normal file
File diff suppressed because it is too large
Load diff
11864
data/langpack/android/android_fi_v59933749.strings
Normal file
11864
data/langpack/android/android_fi_v59933749.strings
Normal file
File diff suppressed because it is too large
Load diff
11861
data/langpack/android/android_fr_v59921990.strings
Normal file
11861
data/langpack/android/android_fr_v59921990.strings
Normal file
File diff suppressed because it is too large
Load diff
13310
data/langpack/android/android_he_v59966306.strings
Normal file
13310
data/langpack/android/android_he_v59966306.strings
Normal file
File diff suppressed because it is too large
Load diff
12610
data/langpack/android/android_hr_v59966087.strings
Normal file
12610
data/langpack/android/android_hr_v59966087.strings
Normal file
File diff suppressed because it is too large
Load diff
11861
data/langpack/android/android_hu_v59906304.strings
Normal file
11861
data/langpack/android/android_hu_v59906304.strings
Normal file
File diff suppressed because it is too large
Load diff
10976
data/langpack/android/android_id_v59866609.strings
Normal file
10976
data/langpack/android/android_id_v59866609.strings
Normal file
File diff suppressed because it is too large
Load diff
11891
data/langpack/android/android_it_v59967903.strings
Normal file
11891
data/langpack/android/android_it_v59967903.strings
Normal file
File diff suppressed because it is too large
Load diff
11867
data/langpack/android/android_kk_v59917391.strings
Normal file
11867
data/langpack/android/android_kk_v59917391.strings
Normal file
File diff suppressed because it is too large
Load diff
11221
data/langpack/android/android_ko_v59946838.strings
Normal file
11221
data/langpack/android/android_ko_v59946838.strings
Normal file
File diff suppressed because it is too large
Load diff
11201
data/langpack/android/android_ms_v59946976.strings
Normal file
11201
data/langpack/android/android_ms_v59946976.strings
Normal file
File diff suppressed because it is too large
Load diff
11870
data/langpack/android/android_nb_v59977190.strings
Normal file
11870
data/langpack/android/android_nb_v59977190.strings
Normal file
File diff suppressed because it is too large
Load diff
11885
data/langpack/android/android_nl_v59914009.strings
Normal file
11885
data/langpack/android/android_nl_v59914009.strings
Normal file
File diff suppressed because it is too large
Load diff
13055
data/langpack/android/android_pl_v59844900.strings
Normal file
13055
data/langpack/android/android_pl_v59844900.strings
Normal file
File diff suppressed because it is too large
Load diff
11919
data/langpack/android/android_pt-br_v59974228.strings
Normal file
11919
data/langpack/android/android_pt-br_v59974228.strings
Normal file
File diff suppressed because it is too large
Load diff
12553
data/langpack/android/android_ro_v59981171.strings
Normal file
12553
data/langpack/android/android_ro_v59981171.strings
Normal file
File diff suppressed because it is too large
Load diff
13343
data/langpack/android/android_ru_v59974213.strings
Normal file
13343
data/langpack/android/android_ru_v59974213.strings
Normal file
File diff suppressed because it is too large
Load diff
10928
data/langpack/android/android_sk_v59822247.strings
Normal file
10928
data/langpack/android/android_sk_v59822247.strings
Normal file
File diff suppressed because it is too large
Load diff
12613
data/langpack/android/android_sr_v59973181.strings
Normal file
12613
data/langpack/android/android_sr_v59973181.strings
Normal file
File diff suppressed because it is too large
Load diff
11844
data/langpack/android/android_sv_v59950998.strings
Normal file
11844
data/langpack/android/android_sv_v59950998.strings
Normal file
File diff suppressed because it is too large
Load diff
11862
data/langpack/android/android_tr_v59920319.strings
Normal file
11862
data/langpack/android/android_tr_v59920319.strings
Normal file
File diff suppressed because it is too large
Load diff
13316
data/langpack/android/android_uk_v59953439.strings
Normal file
13316
data/langpack/android/android_uk_v59953439.strings
Normal file
File diff suppressed because it is too large
Load diff
10876
data/langpack/android/android_uz_v59985112.strings
Normal file
10876
data/langpack/android/android_uz_v59985112.strings
Normal file
File diff suppressed because it is too large
Load diff
10827
data/langpack/android/android_vi_v59453700.strings
Normal file
10827
data/langpack/android/android_vi_v59453700.strings
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -743,7 +743,7 @@
|
|||
"ApproveNewMembersDescriptionFrozen" = "您无法对需要按月付费的链接启用管理员批准。";
|
||||
"ApproveNewMembersDisable" = "禁用";
|
||||
"ApproveNewMembersDisableForLinks#other" = "同时禁用此群组中 %1$d 个现有邀请链接的 **批准新成员** 功能?";
|
||||
"ApproveNewMembersDisableForLinksChannel#other" = "同时禁用此频道中 %1$d 个现有邀请链接的 **批准新成员** 功能?";
|
||||
"ApproveNewMembersDisableForLinksChannel#other" = "同时禁用此频道中 %1$d 个现有邀请链接的**批准新订阅**功能?";
|
||||
"ApproveNewMembersDisabledMessageChannel" = "新订阅者加入此频道前,将不再需要获得 %1$s 的批准。";
|
||||
"ApproveNewMembersDisabledMessageGroup" = "新成员在群内发消息无需再经 **%1$s** 批准。";
|
||||
"ApproveNewMembersEnable" = "启用";
|
||||
|
|
@ -873,7 +873,18 @@
|
|||
"AreYouSureUnsaveSingleMessage" = "您确定要从“我的收藏”中删除此消息吗?";
|
||||
"AreYouSureWebSessions" = "您确定要断开所有使用 Telegram 登录的网站吗?";
|
||||
"ArticleByAuthor" = "作者:%1$s";
|
||||
"ArticleCode" = "代码";
|
||||
"ArticleCommandAudio" = "音频";
|
||||
"ArticleCommandDivider" = "分隔线";
|
||||
"ArticleCommandImage" = "图片";
|
||||
"ArticleCommandMap" = "地图";
|
||||
"ArticleCommandToggle" = "切换";
|
||||
"ArticleCommandVideo" = "Video";
|
||||
"ArticleDateByAuthor" = "%2$s 作于 %1$s";
|
||||
"ArticleHintDetailsTitle" = "标题";
|
||||
"ArticleHintTitle" = "标题";
|
||||
"ArticleNone" = "无";
|
||||
"ArticleText" = "文字";
|
||||
"AskAQuestion" = "向我们提问";
|
||||
"AskAQuestionInfo" = "请注意:Telegram 的支持服务来自志愿者。我们会尽快回复,但仍可能需要等待一段时间。\n\n请前往<![CDATA[<a href=\"https://telegram.org/faq#general-questions\">Telegram 常见问题</a>]]>看看:那里有绝大多数问题的答案和重要的<![CDATA[<a href=\"https://telegram.org/faq#troubleshooting\">故障排除</a>]]>提示。";
|
||||
"AskButton" = "向志愿者提问";
|
||||
|
|
@ -1869,7 +1880,7 @@
|
|||
"BusinessAwayScheduleOutsideHours" = "不在营业时间";
|
||||
"BusinessAwaySend" = "发送离开消息";
|
||||
"BusinessAwayUnsavedChanges" = "您已更改企业离开留言设置,是否应用更改?";
|
||||
"BusinessBotChats" = "机器人可访问的聊天";
|
||||
"BusinessBotChats" = "聊天机器人可访问";
|
||||
"BusinessBotChats2" = "机器人可以访问的聊天";
|
||||
"BusinessBotChatsInfo" = "选择机器人将有权访问的聊天或整个聊天类型。";
|
||||
"BusinessBotChatsInfo2" = "选择机器人不会访问的聊天。";
|
||||
|
|
@ -2707,6 +2718,21 @@
|
|||
"CommentsNoNumber#other" = "评论";
|
||||
"CommentsTitle" = "评论";
|
||||
"CommonGroups#other" = "%1$d 个共同群组";
|
||||
"CommunityAddChatTitle" = "添加聊天";
|
||||
"CommunityAdministrators" = "管理员";
|
||||
"CommunityMenuRemoveBotFromCommunityConfirm" = "您确定要将从社群中移除此机器人吗?";
|
||||
"CommunityMenuRemoveChannelFromCommunityConfirm" = "您确定要将从社群中移除此群组吗?";
|
||||
"CommunityMenuRemoveGroupFromCommunityConfirm" = "您确定要将从社群中移除此群组吗?";
|
||||
"CommunityMenuSettings" = "设置";
|
||||
"CommunityPendingRequestDecline" = "拒绝";
|
||||
"CommunityServiceMessageChannelRemoved" = "**%1$s** 已从社群中移除此频道";
|
||||
"CommunityServiceMessageChannelRemovedUnknown" = "此频道已从社群中移除";
|
||||
"CommunityServiceMessageChannelYouRemoved" = "**You** 已从社群中移除此频道";
|
||||
"CommunityServiceMessageGroupRemoved" = "**%1$s** 已从社群中移除此群组";
|
||||
"CommunityWhoCanAddChatsAllMembers" = " 所有成员";
|
||||
"CommunityWhoCanAddChatsOnlyAdmins" = "仅限管理员";
|
||||
"CommunityYouAreAdminContinue" = "继续";
|
||||
"CommunityYouAreAdminNoThanks" = "不用了,谢谢";
|
||||
"CompatibilityChat" = "%1$s 正在使用旧版 Telegram,因此阅后即焚图片会以兼容模式显示。\n\n当 %2$s 更新 Telegram 后,若阅后即焚计时为 1 分钟或以内,对方可“长按以观看”;对方截屏时,您也会收到通知。";
|
||||
"ConferenceCallIncoming" = "呼入群组通话";
|
||||
"ConferenceCallMissed" = "未接群组通话";
|
||||
|
|
@ -2946,7 +2972,7 @@
|
|||
"DeleteAccountIfAwayFor3" = "保留";
|
||||
"DeleteAccountTitle" = "自动删除帐号";
|
||||
"DeleteAdditionalActions" = "更多选项";
|
||||
"DeleteAlertReaction" = "您确定要删除此用户的回应吗?";
|
||||
"DeleteAlertReaction" = "您确定要删除来自此用户的回应吗?";
|
||||
"DeleteAlertReactionAll" = "删除所有该用户的回应";
|
||||
"DeleteAll" = "删除所有";
|
||||
"DeleteAllCalls" = "删除所有通话";
|
||||
|
|
@ -4563,7 +4589,7 @@
|
|||
"GiftCraftSymbolChance#other" = "制作出的礼物将有 **%1$d%%** 的概率带有 **%2$s** 符号。";
|
||||
"GiftCraftText1" = "最多可添加 **4** 份礼物来制作全新的";
|
||||
"GiftCraftText2" = "**%1$s #%2$s**.\n\n如果制作失败,这些礼物 \n将会 **丟失**。";
|
||||
"GiftCraftTextEmpty1" = "最多可添加 **4** 份礼物来制作全新的";
|
||||
"GiftCraftTextEmpty1" = "至少添加 **4** 份礼物来制作一个新的";
|
||||
"GiftCraftTextEmpty2" = "**%s** 件礼物。\n\n如果制作失败,这些礼物 \n将会 **丟失**。";
|
||||
"GiftCraftTitle" = "制作礼物";
|
||||
"GiftCraftUnavailableText" = "这些礼物目前无法制作。";
|
||||
|
|
@ -6968,6 +6994,9 @@
|
|||
"PmReadTodayAt" = "%s 已读";
|
||||
"PmReadUnknown" = "未知已读时间";
|
||||
"PmReadYesterdayAt" = "昨天 %s 已读";
|
||||
"PmSentDateTimeAt" = "已发送于 %1$s %2$s";
|
||||
"PmSentTodayAt" = "已发送于 %s";
|
||||
"PmSentYesterdayAt" = "已发送于昨天 %s";
|
||||
"Points#other" = "%1$d";
|
||||
"Poll" = "投票";
|
||||
"PollAddAnOption" = "添加选项";
|
||||
|
|
@ -7173,6 +7202,7 @@
|
|||
"PremiumPreviewReactions2" = "无限表情回应";
|
||||
"PremiumPreviewReactions2Description" = "用数千个表情作出回应——可使用多个表情回应单条消息。";
|
||||
"PremiumPreviewReactionsDescription" = "使用更多动画表情回应消息,仅高级版订阅者可用。";
|
||||
"PremiumPreviewRichEditorDescription" = "在消息中添加标题、表格、内嵌媒体和 AI 内容。";
|
||||
"PremiumPreviewSharingDisable" = "禁用分享";
|
||||
"PremiumPreviewSharingDisableDescription" = "禁用私聊中的截屏、收藏和转发消息功能。";
|
||||
"PremiumPreviewStickers" = "高级版贴纸";
|
||||
|
|
@ -7907,7 +7937,7 @@
|
|||
"ResellGiftInfoMinTON" = "最低价格为 %s Gram";
|
||||
"ResellGiftInfoTON" = "您将收到 **%s** Gram。";
|
||||
"ResellGiftPriceHintOnlyTON" = "如果买家使用 Gram 付款,则不存在买家要求退款的风险,\n这是与星星付款的不同之处。";
|
||||
"ResellGiftPriceOnlyTON" = "只接受以 Gram 付款";
|
||||
"ResellGiftPriceOnlyTON" = "仅接受 Gram";
|
||||
"ResellGiftPriceTitle" = "以星星作为单位输入价格";
|
||||
"ResellGiftPriceTitleTON" = "输入 Gram 价格";
|
||||
"ResellGiftPriceTooMuch" = "您最高可以报价 %s";
|
||||
|
|
@ -10805,7 +10835,7 @@
|
|||
"WebBrowserExceptionsLimitMessage" = "\n网站例外数量已达上限。请先移除部分现有例外,再添加新的。";
|
||||
"WebBrowserExceptionsLimitTitle" = "已达上限";
|
||||
"WebBrowserShowCloseButton" = "显示关闭按钮";
|
||||
"WebBrowserShowCloseButtonInfo" = "浏览网页时添加关闭按钮";
|
||||
"WebBrowserShowCloseButtonInfo" = "在 Telegram 内打开外部浏览器。";
|
||||
"WebDownloadAlertInfo" = "开始下载 **%s**?";
|
||||
"WebDownloadAlertInfoWithSize" = "开始下载 **%1$s** (%2$s)?";
|
||||
"WebDownloadAlertTitle" = "下载文件";
|
||||
11201
data/langpack/android/android_zh-hant_v59979378.strings
Normal file
11201
data/langpack/android/android_zh-hant_v59979378.strings
Normal file
File diff suppressed because it is too large
Load diff
6483
data/langpack/android_x/android_x_ar_v1623895.strings
Normal file
6483
data/langpack/android_x/android_x_ar_v1623895.strings
Normal file
File diff suppressed because it is too large
Load diff
5067
data/langpack/android_x/android_x_be_v1623843.strings
Normal file
5067
data/langpack/android_x/android_x_be_v1623843.strings
Normal file
File diff suppressed because it is too large
Load diff
5168
data/langpack/android_x/android_x_ca_v1621108.strings
Normal file
5168
data/langpack/android_x/android_x_ca_v1621108.strings
Normal file
File diff suppressed because it is too large
Load diff
6150
data/langpack/android_x/android_x_cs_v1623534.strings
Normal file
6150
data/langpack/android_x/android_x_cs_v1623534.strings
Normal file
File diff suppressed because it is too large
Load diff
3894
data/langpack/android_x/android_x_de_v1617403.strings
Normal file
3894
data/langpack/android_x/android_x_de_v1617403.strings
Normal file
File diff suppressed because it is too large
Load diff
5128
data/langpack/android_x/android_x_en_v1619065.strings
Normal file
5128
data/langpack/android_x/android_x_en_v1619065.strings
Normal file
File diff suppressed because it is too large
Load diff
3600
data/langpack/android_x/android_x_eo_v1581671.strings
Normal file
3600
data/langpack/android_x/android_x_eo_v1581671.strings
Normal file
File diff suppressed because it is too large
Load diff
5168
data/langpack/android_x/android_x_es_v1621303.strings
Normal file
5168
data/langpack/android_x/android_x_es_v1621303.strings
Normal file
File diff suppressed because it is too large
Load diff
5119
data/langpack/android_x/android_x_fa_v1618464.strings
Normal file
5119
data/langpack/android_x/android_x_fa_v1618464.strings
Normal file
File diff suppressed because it is too large
Load diff
5168
data/langpack/android_x/android_x_fi_v1623250.strings
Normal file
5168
data/langpack/android_x/android_x_fi_v1623250.strings
Normal file
File diff suppressed because it is too large
Load diff
5168
data/langpack/android_x/android_x_fr_v1623248.strings
Normal file
5168
data/langpack/android_x/android_x_fr_v1623248.strings
Normal file
File diff suppressed because it is too large
Load diff
6152
data/langpack/android_x/android_x_he_v1623787.strings
Normal file
6152
data/langpack/android_x/android_x_he_v1623787.strings
Normal file
File diff suppressed because it is too large
Load diff
5451
data/langpack/android_x/android_x_hr_v1623294.strings
Normal file
5451
data/langpack/android_x/android_x_hr_v1623294.strings
Normal file
File diff suppressed because it is too large
Load diff
5120
data/langpack/android_x/android_x_hu_v1620856.strings
Normal file
5120
data/langpack/android_x/android_x_hu_v1620856.strings
Normal file
File diff suppressed because it is too large
Load diff
5168
data/langpack/android_x/android_x_it_v1621269.strings
Normal file
5168
data/langpack/android_x/android_x_it_v1621269.strings
Normal file
File diff suppressed because it is too large
Load diff
5168
data/langpack/android_x/android_x_kk_v1623033.strings
Normal file
5168
data/langpack/android_x/android_x_kk_v1623033.strings
Normal file
File diff suppressed because it is too large
Load diff
4676
data/langpack/android_x/android_x_ko_v1621784.strings
Normal file
4676
data/langpack/android_x/android_x_ko_v1621784.strings
Normal file
File diff suppressed because it is too large
Load diff
3190
data/langpack/android_x/android_x_ml_v1555695.strings
Normal file
3190
data/langpack/android_x/android_x_ml_v1555695.strings
Normal file
File diff suppressed because it is too large
Load diff
4676
data/langpack/android_x/android_x_ms_v1623219.strings
Normal file
4676
data/langpack/android_x/android_x_ms_v1623219.strings
Normal file
File diff suppressed because it is too large
Load diff
5168
data/langpack/android_x/android_x_nb_v1623870.strings
Normal file
5168
data/langpack/android_x/android_x_nb_v1623870.strings
Normal file
File diff suppressed because it is too large
Load diff
5757
data/langpack/android_x/android_x_pl_v1621110.strings
Normal file
5757
data/langpack/android_x/android_x_pl_v1621110.strings
Normal file
File diff suppressed because it is too large
Load diff
5168
data/langpack/android_x/android_x_pt-br_v1623582.strings
Normal file
5168
data/langpack/android_x/android_x_pt-br_v1623582.strings
Normal file
File diff suppressed because it is too large
Load diff
5653
data/langpack/android_x/android_x_ro_v1621247.strings
Normal file
5653
data/langpack/android_x/android_x_ro_v1621247.strings
Normal file
File diff suppressed because it is too large
Load diff
6152
data/langpack/android_x/android_x_ru_v1620897.strings
Normal file
6152
data/langpack/android_x/android_x_ru_v1620897.strings
Normal file
File diff suppressed because it is too large
Load diff
5396
data/langpack/android_x/android_x_sk_v1618398.strings
Normal file
5396
data/langpack/android_x/android_x_sk_v1618398.strings
Normal file
File diff suppressed because it is too large
Load diff
5660
data/langpack/android_x/android_x_sr_v1623148.strings
Normal file
5660
data/langpack/android_x/android_x_sr_v1623148.strings
Normal file
File diff suppressed because it is too large
Load diff
5168
data/langpack/android_x/android_x_sv_v1623532.strings
Normal file
5168
data/langpack/android_x/android_x_sv_v1623532.strings
Normal file
File diff suppressed because it is too large
Load diff
5128
data/langpack/android_x/android_x_ta_v1614352.strings
Normal file
5128
data/langpack/android_x/android_x_ta_v1614352.strings
Normal file
File diff suppressed because it is too large
Load diff
4007
data/langpack/android_x/android_x_tr_v1604803.strings
Normal file
4007
data/langpack/android_x/android_x_tr_v1604803.strings
Normal file
File diff suppressed because it is too large
Load diff
6064
data/langpack/android_x/android_x_uk_v1623660.strings
Normal file
6064
data/langpack/android_x/android_x_uk_v1623660.strings
Normal file
File diff suppressed because it is too large
Load diff
4622
data/langpack/android_x/android_x_vi_v1602260.strings
Normal file
4622
data/langpack/android_x/android_x_vi_v1602260.strings
Normal file
File diff suppressed because it is too large
Load diff
4501
data/langpack/android_x/android_x_zh-hans_v1619347.strings
Normal file
4501
data/langpack/android_x/android_x_zh-hans_v1619347.strings
Normal file
File diff suppressed because it is too large
Load diff
4676
data/langpack/android_x/android_x_zh-hant_v1622408.strings
Normal file
4676
data/langpack/android_x/android_x_zh-hant_v1622408.strings
Normal file
File diff suppressed because it is too large
Load diff
14895
data/langpack/ios/ios_ar_v21554106.strings
Normal file
14895
data/langpack/ios/ios_ar_v21554106.strings
Normal file
File diff suppressed because it is too large
Load diff
13965
data/langpack/ios/ios_be_v21547555.strings
Normal file
13965
data/langpack/ios/ios_be_v21547555.strings
Normal file
File diff suppressed because it is too large
Load diff
12597
data/langpack/ios/ios_ca_v21546564.strings
Normal file
12597
data/langpack/ios/ios_ca_v21546564.strings
Normal file
File diff suppressed because it is too large
Load diff
14016
data/langpack/ios/ios_cs_v21519219.strings
Normal file
14016
data/langpack/ios/ios_cs_v21519219.strings
Normal file
File diff suppressed because it is too large
Load diff
12596
data/langpack/ios/ios_de_v21536099.strings
Normal file
12596
data/langpack/ios/ios_de_v21536099.strings
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -3231,7 +3231,7 @@
|
|||
"ChatbotSetup.BotNotFoundStatus" = "Chatbot not found";
|
||||
"ChatbotSetup.BotSearchPlaceholder" = "Bot Username or Link";
|
||||
"ChatbotSetup.BotSectionFooter" = "Choose a bot to manage your chats automatically.";
|
||||
"ChatbotSetup.ErrorBotNotBusinessCapable" = "This bot doesn't support Telegram Business yet.";
|
||||
"ChatbotSetup.ErrorBotNotBusinessCapable" = "This bot doesn't support Secretary Mode yet.";
|
||||
"ChatbotSetup.Gift.Warning.CombinedText" = "The bot **%@** will be able to **manage your gifts and stars**, including giving them away to other users.";
|
||||
"ChatbotSetup.Gift.Warning.GiftsText" = "The bot **%@** will be able to **manage your gifts**, including giving them away to other users.";
|
||||
"ChatbotSetup.Gift.Warning.Proceed" = "Proceed";
|
||||
12596
data/langpack/ios/ios_es_v21538743.strings
Normal file
12596
data/langpack/ios/ios_es_v21538743.strings
Normal file
File diff suppressed because it is too large
Load diff
12255
data/langpack/ios/ios_fa_v21515079.strings
Normal file
12255
data/langpack/ios/ios_fa_v21515079.strings
Normal file
File diff suppressed because it is too large
Load diff
12597
data/langpack/ios/ios_fi_v21552839.strings
Normal file
12597
data/langpack/ios/ios_fi_v21552839.strings
Normal file
File diff suppressed because it is too large
Load diff
12587
data/langpack/ios/ios_fr_v21511263.strings
Normal file
12587
data/langpack/ios/ios_fr_v21511263.strings
Normal file
File diff suppressed because it is too large
Load diff
14011
data/langpack/ios/ios_he_v21546080.strings
Normal file
14011
data/langpack/ios/ios_he_v21546080.strings
Normal file
File diff suppressed because it is too large
Load diff
13301
data/langpack/ios/ios_hr_v21545920.strings
Normal file
13301
data/langpack/ios/ios_hr_v21545920.strings
Normal file
File diff suppressed because it is too large
Load diff
12542
data/langpack/ios/ios_hu_v21506944.strings
Normal file
12542
data/langpack/ios/ios_hu_v21506944.strings
Normal file
File diff suppressed because it is too large
Load diff
11671
data/langpack/ios/ios_id_v21491615.strings
Normal file
11671
data/langpack/ios/ios_id_v21491615.strings
Normal file
File diff suppressed because it is too large
Load diff
12596
data/langpack/ios/ios_it_v21546733.strings
Normal file
12596
data/langpack/ios/ios_it_v21546733.strings
Normal file
File diff suppressed because it is too large
Load diff
12597
data/langpack/ios/ios_kk_v21553952.strings
Normal file
12597
data/langpack/ios/ios_kk_v21553952.strings
Normal file
File diff suppressed because it is too large
Load diff
11883
data/langpack/ios/ios_ko_v21535953.strings
Normal file
11883
data/langpack/ios/ios_ko_v21535953.strings
Normal file
File diff suppressed because it is too large
Load diff
11883
data/langpack/ios/ios_ms_v21552746.strings
Normal file
11883
data/langpack/ios/ios_ms_v21552746.strings
Normal file
File diff suppressed because it is too large
Load diff
12431
data/langpack/ios/ios_nb_v21553405.strings
Normal file
12431
data/langpack/ios/ios_nb_v21553405.strings
Normal file
File diff suppressed because it is too large
Load diff
12596
data/langpack/ios/ios_nl_v21554810.strings
Normal file
12596
data/langpack/ios/ios_nl_v21554810.strings
Normal file
File diff suppressed because it is too large
Load diff
13831
data/langpack/ios/ios_pl_v21447117.strings
Normal file
13831
data/langpack/ios/ios_pl_v21447117.strings
Normal file
File diff suppressed because it is too large
Load diff
12597
data/langpack/ios/ios_pt-br_v21552845.strings
Normal file
12597
data/langpack/ios/ios_pt-br_v21552845.strings
Normal file
File diff suppressed because it is too large
Load diff
13308
data/langpack/ios/ios_ro_v21546565.strings
Normal file
13308
data/langpack/ios/ios_ro_v21546565.strings
Normal file
File diff suppressed because it is too large
Load diff
14018
data/langpack/ios/ios_ru_v21552838.strings
Normal file
14018
data/langpack/ios/ios_ru_v21552838.strings
Normal file
File diff suppressed because it is too large
Load diff
12953
data/langpack/ios/ios_sk_v21453335.strings
Normal file
12953
data/langpack/ios/ios_sk_v21453335.strings
Normal file
File diff suppressed because it is too large
Load diff
13311
data/langpack/ios/ios_sr_v21545085.strings
Normal file
13311
data/langpack/ios/ios_sr_v21545085.strings
Normal file
File diff suppressed because it is too large
Load diff
12589
data/langpack/ios/ios_sv_v21514892.strings
Normal file
12589
data/langpack/ios/ios_sv_v21514892.strings
Normal file
File diff suppressed because it is too large
Load diff
12589
data/langpack/ios/ios_tr_v21517866.strings
Normal file
12589
data/langpack/ios/ios_tr_v21517866.strings
Normal file
File diff suppressed because it is too large
Load diff
14015
data/langpack/ios/ios_uk_v21537819.strings
Normal file
14015
data/langpack/ios/ios_uk_v21537819.strings
Normal file
File diff suppressed because it is too large
Load diff
11215
data/langpack/ios/ios_uz_v21554962.strings
Normal file
11215
data/langpack/ios/ios_uz_v21554962.strings
Normal file
File diff suppressed because it is too large
Load diff
11460
data/langpack/ios/ios_vi_v21202542.strings
Normal file
11460
data/langpack/ios/ios_vi_v21202542.strings
Normal file
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue