diff options
author | Chocobozzz <me@florianbigard.com> | 2018-06-06 16:46:42 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-06-06 16:48:41 +0200 |
commit | 7ce44a74a3b052190cfacd4bd5ee6b92cfc620ac (patch) | |
tree | 6f178426c165f9136eb08354efa4a06c24725f87 | |
parent | f07d6385b4b46c3254898292a8a53ed415b8d49b (diff) | |
download | PeerTube-7ce44a74a3b052190cfacd4bd5ee6b92cfc620ac.tar.gz PeerTube-7ce44a74a3b052190cfacd4bd5ee6b92cfc620ac.tar.zst PeerTube-7ce44a74a3b052190cfacd4bd5ee6b92cfc620ac.zip |
Add server localization
-rw-r--r-- | client/src/app/core/server/server.service.ts | 76 | ||||
-rw-r--r-- | client/src/app/shared/i18n/i18n-utils.ts | 7 | ||||
-rw-r--r-- | client/src/app/shared/video/video-details.model.ts | 4 | ||||
-rw-r--r-- | client/src/app/shared/video/video.model.ts | 8 | ||||
-rw-r--r-- | client/src/app/shared/video/video.service.ts | 56 | ||||
-rw-r--r-- | client/src/locale/source/server_en_US.xml | 878 | ||||
-rw-r--r-- | client/src/locale/target/player_fr.xml | 379 | ||||
-rw-r--r-- | client/src/locale/target/server_fr.json | 1 | ||||
-rwxr-xr-x | scripts/i18n/create-custom-files.ts | 70 | ||||
-rwxr-xr-x | scripts/i18n/xliff2json.ts | 62 | ||||
-rw-r--r-- | server/controllers/client.ts | 7 | ||||
-rw-r--r-- | server/initializers/constants.ts | 3 |
12 files changed, 1080 insertions, 471 deletions
diff --git a/client/src/app/core/server/server.service.ts b/client/src/app/core/server/server.service.ts index ccae5a151..56d33339e 100644 --- a/client/src/app/core/server/server.service.ts +++ b/client/src/app/core/server/server.service.ts | |||
@@ -1,17 +1,20 @@ | |||
1 | import { tap } from 'rxjs/operators' | 1 | import { map, share, switchMap, tap } from 'rxjs/operators' |
2 | import { HttpClient } from '@angular/common/http' | 2 | import { HttpClient } from '@angular/common/http' |
3 | import { Injectable } from '@angular/core' | 3 | import { Inject, Injectable, LOCALE_ID } from '@angular/core' |
4 | import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' | 4 | import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' |
5 | import { ReplaySubject } from 'rxjs' | 5 | import { Observable, ReplaySubject } from 'rxjs' |
6 | import { ServerConfig } from '../../../../../shared' | 6 | import { ServerConfig } from '../../../../../shared' |
7 | import { About } from '../../../../../shared/models/server/about.model' | 7 | import { About } from '../../../../../shared/models/server/about.model' |
8 | import { environment } from '../../../environments/environment' | 8 | import { environment } from '../../../environments/environment' |
9 | import { VideoConstant, VideoPrivacy } from '../../../../../shared/models/videos' | 9 | import { VideoConstant, VideoPrivacy } from '../../../../../shared/models/videos' |
10 | import { buildFileLocale, getDefaultLocale } from '../../../../../shared/models/i18n' | ||
11 | import { peertubeTranslate } from '@app/shared/i18n/i18n-utils' | ||
10 | 12 | ||
11 | @Injectable() | 13 | @Injectable() |
12 | export class ServerService { | 14 | export class ServerService { |
13 | private static BASE_CONFIG_URL = environment.apiUrl + '/api/v1/config/' | 15 | private static BASE_CONFIG_URL = environment.apiUrl + '/api/v1/config/' |
14 | private static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos/' | 16 | private static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos/' |
17 | private static BASE_LOCALE_URL = environment.apiUrl + '/client/locales/' | ||
15 | private static CONFIG_LOCAL_STORAGE_KEY = 'server-config' | 18 | private static CONFIG_LOCAL_STORAGE_KEY = 'server-config' |
16 | 19 | ||
17 | configLoaded = new ReplaySubject<boolean>(1) | 20 | configLoaded = new ReplaySubject<boolean>(1) |
@@ -19,6 +22,7 @@ export class ServerService { | |||
19 | videoCategoriesLoaded = new ReplaySubject<boolean>(1) | 22 | videoCategoriesLoaded = new ReplaySubject<boolean>(1) |
20 | videoLicencesLoaded = new ReplaySubject<boolean>(1) | 23 | videoLicencesLoaded = new ReplaySubject<boolean>(1) |
21 | videoLanguagesLoaded = new ReplaySubject<boolean>(1) | 24 | videoLanguagesLoaded = new ReplaySubject<boolean>(1) |
25 | localeObservable: Observable<any> | ||
22 | 26 | ||
23 | private config: ServerConfig = { | 27 | private config: ServerConfig = { |
24 | instance: { | 28 | instance: { |
@@ -64,8 +68,12 @@ export class ServerService { | |||
64 | private videoLanguages: Array<VideoConstant<string>> = [] | 68 | private videoLanguages: Array<VideoConstant<string>> = [] |
65 | private videoPrivacies: Array<VideoConstant<VideoPrivacy>> = [] | 69 | private videoPrivacies: Array<VideoConstant<VideoPrivacy>> = [] |
66 | 70 | ||
67 | constructor (private http: HttpClient) { | 71 | constructor ( |
72 | private http: HttpClient, | ||
73 | @Inject(LOCALE_ID) private localeId: string | ||
74 | ) { | ||
68 | this.loadConfigLocally() | 75 | this.loadConfigLocally() |
76 | this.loadServerLocale() | ||
69 | } | 77 | } |
70 | 78 | ||
71 | loadConfig () { | 79 | loadConfig () { |
@@ -124,26 +132,46 @@ export class ServerService { | |||
124 | notifier: ReplaySubject<boolean>, | 132 | notifier: ReplaySubject<boolean>, |
125 | sort = false | 133 | sort = false |
126 | ) { | 134 | ) { |
127 | return this.http.get(ServerService.BASE_VIDEO_URL + attributeName) | 135 | this.localeObservable |
128 | .subscribe(data => { | 136 | .pipe( |
129 | Object.keys(data) | 137 | switchMap(translations => { |
130 | .forEach(dataKey => { | 138 | return this.http.get(ServerService.BASE_VIDEO_URL + attributeName) |
131 | hashToPopulate.push({ | 139 | .pipe(map(data => ({ data, translations }))) |
132 | id: dataKey, | 140 | }) |
133 | label: data[dataKey] | 141 | ) |
134 | }) | 142 | .subscribe(({ data, translations }) => { |
135 | }) | 143 | Object.keys(data) |
136 | 144 | .forEach(dataKey => { | |
137 | if (sort === true) { | 145 | const label = data[ dataKey ] |
138 | hashToPopulate.sort((a, b) => { | 146 | |
139 | if (a.label < b.label) return -1 | 147 | hashToPopulate.push({ |
140 | if (a.label === b.label) return 0 | 148 | id: dataKey, |
141 | return 1 | 149 | label: peertubeTranslate(label, translations) |
142 | }) | 150 | }) |
143 | } | 151 | }) |
144 | 152 | ||
145 | notifier.next(true) | 153 | if (sort === true) { |
146 | }) | 154 | hashToPopulate.sort((a, b) => { |
155 | if (a.label < b.label) return -1 | ||
156 | if (a.label === b.label) return 0 | ||
157 | return 1 | ||
158 | }) | ||
159 | } | ||
160 | |||
161 | notifier.next(true) | ||
162 | }) | ||
163 | } | ||
164 | |||
165 | private loadServerLocale () { | ||
166 | const fileLocale = buildFileLocale(environment.production === true ? this.localeId : 'fr') | ||
167 | |||
168 | // Default locale, nothing to translate | ||
169 | const defaultFileLocale = buildFileLocale(getDefaultLocale()) | ||
170 | if (fileLocale === defaultFileLocale) return {} | ||
171 | |||
172 | this.localeObservable = this.http | ||
173 | .get(ServerService.BASE_LOCALE_URL + fileLocale + '/server.json') | ||
174 | .pipe(share()) | ||
147 | } | 175 | } |
148 | 176 | ||
149 | private saveConfigLocally (config: ServerConfig) { | 177 | private saveConfigLocally (config: ServerConfig) { |
diff --git a/client/src/app/shared/i18n/i18n-utils.ts b/client/src/app/shared/i18n/i18n-utils.ts new file mode 100644 index 000000000..c1de51b7b --- /dev/null +++ b/client/src/app/shared/i18n/i18n-utils.ts | |||
@@ -0,0 +1,7 @@ | |||
1 | function peertubeTranslate (str: string, translations: { [ id: string ]: string }) { | ||
2 | return translations[str] ? translations[str] : str | ||
3 | } | ||
4 | |||
5 | export { | ||
6 | peertubeTranslate | ||
7 | } | ||
diff --git a/client/src/app/shared/video/video-details.model.ts b/client/src/app/shared/video/video-details.model.ts index 5fc55fca6..19c350ab3 100644 --- a/client/src/app/shared/video/video-details.model.ts +++ b/client/src/app/shared/video/video-details.model.ts | |||
@@ -15,8 +15,8 @@ export class VideoDetails extends Video implements VideoDetailsServerModel { | |||
15 | likesPercent: number | 15 | likesPercent: number |
16 | dislikesPercent: number | 16 | dislikesPercent: number |
17 | 17 | ||
18 | constructor (hash: VideoDetailsServerModel) { | 18 | constructor (hash: VideoDetailsServerModel, translations = {}) { |
19 | super(hash) | 19 | super(hash, translations) |
20 | 20 | ||
21 | this.descriptionPath = hash.descriptionPath | 21 | this.descriptionPath = hash.descriptionPath |
22 | this.files = hash.files | 22 | this.files = hash.files |
diff --git a/client/src/app/shared/video/video.model.ts b/client/src/app/shared/video/video.model.ts index 48d562f9c..d37dc2c3e 100644 --- a/client/src/app/shared/video/video.model.ts +++ b/client/src/app/shared/video/video.model.ts | |||
@@ -5,6 +5,7 @@ import { VideoConstant } from '../../../../../shared/models/videos/video.model' | |||
5 | import { getAbsoluteAPIUrl } from '../misc/utils' | 5 | import { getAbsoluteAPIUrl } from '../misc/utils' |
6 | import { ServerConfig } from '../../../../../shared/models' | 6 | import { ServerConfig } from '../../../../../shared/models' |
7 | import { Actor } from '@app/shared/actor/actor.model' | 7 | import { Actor } from '@app/shared/actor/actor.model' |
8 | import { peertubeTranslate } from '@app/shared/i18n/i18n-utils' | ||
8 | 9 | ||
9 | export class Video implements VideoServerModel { | 10 | export class Video implements VideoServerModel { |
10 | by: string | 11 | by: string |
@@ -68,7 +69,7 @@ export class Video implements VideoServerModel { | |||
68 | minutes.toString() + ':' + secondsPadding + seconds.toString() | 69 | minutes.toString() + ':' + secondsPadding + seconds.toString() |
69 | } | 70 | } |
70 | 71 | ||
71 | constructor (hash: VideoServerModel) { | 72 | constructor (hash: VideoServerModel, translations = {}) { |
72 | const absoluteAPIUrl = getAbsoluteAPIUrl() | 73 | const absoluteAPIUrl = getAbsoluteAPIUrl() |
73 | 74 | ||
74 | this.createdAt = new Date(hash.createdAt.toString()) | 75 | this.createdAt = new Date(hash.createdAt.toString()) |
@@ -98,6 +99,11 @@ export class Video implements VideoServerModel { | |||
98 | 99 | ||
99 | this.by = Actor.CREATE_BY_STRING(hash.account.name, hash.account.host) | 100 | this.by = Actor.CREATE_BY_STRING(hash.account.name, hash.account.host) |
100 | this.accountAvatarUrl = Actor.GET_ACTOR_AVATAR_URL(this.account) | 101 | this.accountAvatarUrl = Actor.GET_ACTOR_AVATAR_URL(this.account) |
102 | |||
103 | this.category.label = peertubeTranslate(this.category.label, translations) | ||
104 | this.licence.label = peertubeTranslate(this.licence.label, translations) | ||
105 | this.language.label = peertubeTranslate(this.language.label, translations) | ||
106 | this.privacy.label = peertubeTranslate(this.privacy.label, translations) | ||
101 | } | 107 | } |
102 | 108 | ||
103 | isVideoNSFWForUser (user: User, serverConfig: ServerConfig) { | 109 | isVideoNSFWForUser (user: User, serverConfig: ServerConfig) { |
diff --git a/client/src/app/shared/video/video.service.ts b/client/src/app/shared/video/video.service.ts index d1e32faeb..c607b7d6a 100644 --- a/client/src/app/shared/video/video.service.ts +++ b/client/src/app/shared/video/video.service.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { catchError, map } from 'rxjs/operators' | 1 | import { catchError, map, switchMap } from 'rxjs/operators' |
2 | import { HttpClient, HttpParams, HttpRequest } from '@angular/common/http' | 2 | import { HttpClient, HttpParams, HttpRequest } from '@angular/common/http' |
3 | import { Injectable } from '@angular/core' | 3 | import { Injectable } from '@angular/core' |
4 | import { Observable } from 'rxjs' | 4 | import { Observable } from 'rxjs' |
@@ -24,6 +24,7 @@ import { Account } from '@app/shared/account/account.model' | |||
24 | import { AccountService } from '@app/shared/account/account.service' | 24 | import { AccountService } from '@app/shared/account/account.service' |
25 | import { VideoChannel } from '../../../../../shared/models/videos' | 25 | import { VideoChannel } from '../../../../../shared/models/videos' |
26 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' | 26 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' |
27 | import { ServerService } from '@app/core' | ||
27 | 28 | ||
28 | @Injectable() | 29 | @Injectable() |
29 | export class VideoService { | 30 | export class VideoService { |
@@ -33,7 +34,8 @@ export class VideoService { | |||
33 | constructor ( | 34 | constructor ( |
34 | private authHttp: HttpClient, | 35 | private authHttp: HttpClient, |
35 | private restExtractor: RestExtractor, | 36 | private restExtractor: RestExtractor, |
36 | private restService: RestService | 37 | private restService: RestService, |
38 | private serverService: ServerService | ||
37 | ) {} | 39 | ) {} |
38 | 40 | ||
39 | getVideoViewUrl (uuid: string) { | 41 | getVideoViewUrl (uuid: string) { |
@@ -41,9 +43,13 @@ export class VideoService { | |||
41 | } | 43 | } |
42 | 44 | ||
43 | getVideo (uuid: string): Observable<VideoDetails> { | 45 | getVideo (uuid: string): Observable<VideoDetails> { |
44 | return this.authHttp.get<VideoDetailsServerModel>(VideoService.BASE_VIDEO_URL + uuid) | 46 | return this.serverService.localeObservable |
45 | .pipe( | 47 | .pipe( |
46 | map(videoHash => new VideoDetails(videoHash)), | 48 | switchMap(translations => { |
49 | return this.authHttp.get<VideoDetailsServerModel>(VideoService.BASE_VIDEO_URL + uuid) | ||
50 | .pipe(map(videoHash => ({ videoHash, translations }))) | ||
51 | }), | ||
52 | map(({ videoHash, translations }) => new VideoDetails(videoHash, translations)), | ||
47 | catchError(res => this.restExtractor.handleError(res)) | 53 | catchError(res => this.restExtractor.handleError(res)) |
48 | ) | 54 | ) |
49 | } | 55 | } |
@@ -102,9 +108,10 @@ export class VideoService { | |||
102 | let params = new HttpParams() | 108 | let params = new HttpParams() |
103 | params = this.restService.addRestGetParams(params, pagination, sort) | 109 | params = this.restService.addRestGetParams(params, pagination, sort) |
104 | 110 | ||
105 | return this.authHttp.get(UserService.BASE_USERS_URL + '/me/videos', { params }) | 111 | return this.authHttp |
112 | .get<ResultList<Video>>(UserService.BASE_USERS_URL + '/me/videos', { params }) | ||
106 | .pipe( | 113 | .pipe( |
107 | map(this.extractVideos), | 114 | switchMap(res => this.extractVideos(res)), |
108 | catchError(res => this.restExtractor.handleError(res)) | 115 | catchError(res => this.restExtractor.handleError(res)) |
109 | ) | 116 | ) |
110 | } | 117 | } |
@@ -120,9 +127,9 @@ export class VideoService { | |||
120 | params = this.restService.addRestGetParams(params, pagination, sort) | 127 | params = this.restService.addRestGetParams(params, pagination, sort) |
121 | 128 | ||
122 | return this.authHttp | 129 | return this.authHttp |
123 | .get(AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/videos', { params }) | 130 | .get<ResultList<Video>>(AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/videos', { params }) |
124 | .pipe( | 131 | .pipe( |
125 | map(this.extractVideos), | 132 | switchMap(res => this.extractVideos(res)), |
126 | catchError(res => this.restExtractor.handleError(res)) | 133 | catchError(res => this.restExtractor.handleError(res)) |
127 | ) | 134 | ) |
128 | } | 135 | } |
@@ -138,9 +145,9 @@ export class VideoService { | |||
138 | params = this.restService.addRestGetParams(params, pagination, sort) | 145 | params = this.restService.addRestGetParams(params, pagination, sort) |
139 | 146 | ||
140 | return this.authHttp | 147 | return this.authHttp |
141 | .get(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannel.uuid + '/videos', { params }) | 148 | .get<ResultList<Video>>(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannel.uuid + '/videos', { params }) |
142 | .pipe( | 149 | .pipe( |
143 | map(this.extractVideos), | 150 | switchMap(res => this.extractVideos(res)), |
144 | catchError(res => this.restExtractor.handleError(res)) | 151 | catchError(res => this.restExtractor.handleError(res)) |
145 | ) | 152 | ) |
146 | } | 153 | } |
@@ -160,9 +167,9 @@ export class VideoService { | |||
160 | } | 167 | } |
161 | 168 | ||
162 | return this.authHttp | 169 | return this.authHttp |
163 | .get(VideoService.BASE_VIDEO_URL, { params }) | 170 | .get<ResultList<Video>>(VideoService.BASE_VIDEO_URL, { params }) |
164 | .pipe( | 171 | .pipe( |
165 | map(this.extractVideos), | 172 | switchMap(res => this.extractVideos(res)), |
166 | catchError(res => this.restExtractor.handleError(res)) | 173 | catchError(res => this.restExtractor.handleError(res)) |
167 | ) | 174 | ) |
168 | } | 175 | } |
@@ -230,7 +237,7 @@ export class VideoService { | |||
230 | return this.authHttp | 237 | return this.authHttp |
231 | .get<ResultList<VideoServerModel>>(url, { params }) | 238 | .get<ResultList<VideoServerModel>>(url, { params }) |
232 | .pipe( | 239 | .pipe( |
233 | map(this.extractVideos), | 240 | switchMap(res => this.extractVideos(res)), |
234 | catchError(res => this.restExtractor.handleError(res)) | 241 | catchError(res => this.restExtractor.handleError(res)) |
235 | ) | 242 | ) |
236 | } | 243 | } |
@@ -287,14 +294,19 @@ export class VideoService { | |||
287 | } | 294 | } |
288 | 295 | ||
289 | private extractVideos (result: ResultList<VideoServerModel>) { | 296 | private extractVideos (result: ResultList<VideoServerModel>) { |
290 | const videosJson = result.data | 297 | return this.serverService.localeObservable |
291 | const totalVideos = result.total | 298 | .pipe( |
292 | const videos = [] | 299 | map(translations => { |
293 | 300 | const videosJson = result.data | |
294 | for (const videoJson of videosJson) { | 301 | const totalVideos = result.total |
295 | videos.push(new Video(videoJson)) | 302 | const videos: Video[] = [] |
296 | } | 303 | |
297 | 304 | for (const videoJson of videosJson) { | |
298 | return { videos, totalVideos } | 305 | videos.push(new Video(videoJson, translations)) |
306 | } | ||
307 | |||
308 | return { videos, totalVideos } | ||
309 | }) | ||
310 | ) | ||
299 | } | 311 | } |
300 | } | 312 | } |
diff --git a/client/src/locale/source/server_en_US.xml b/client/src/locale/source/server_en_US.xml new file mode 100644 index 000000000..dab91f98d --- /dev/null +++ b/client/src/locale/source/server_en_US.xml | |||
@@ -0,0 +1,878 @@ | |||
1 | <xliff xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 http://docs.oasis-open.org/xliff/v1.2/os/xliff-core-1.2-strict.xsd" xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2"> | ||
2 | <file original="namespace1" datatype="plaintext" source-language="undefined" target-language="undefined"> | ||
3 | <body> | ||
4 | <trans-unit id="Music"> | ||
5 | <source>Music</source> | ||
6 | <target>undefined</target> | ||
7 | </trans-unit> | ||
8 | <trans-unit id="Films"> | ||
9 | <source>Films</source> | ||
10 | <target>undefined</target> | ||
11 | </trans-unit> | ||
12 | <trans-unit id="Vehicles"> | ||
13 | <source>Vehicles</source> | ||
14 | <target>undefined</target> | ||
15 | </trans-unit> | ||
16 | <trans-unit id="Art"> | ||
17 | <source>Art</source> | ||
18 | <target>undefined</target> | ||
19 | </trans-unit> | ||
20 | <trans-unit id="Sports"> | ||
21 | <source>Sports</source> | ||
22 | <target>undefined</target> | ||
23 | </trans-unit> | ||
24 | <trans-unit id="Travels"> | ||
25 | <source>Travels</source> | ||
26 | <target>undefined</target> | ||
27 | </trans-unit> | ||
28 | <trans-unit id="Gaming"> | ||
29 | <source>Gaming</source> | ||
30 | <target>undefined</target> | ||
31 | </trans-unit> | ||
32 | <trans-unit id="People"> | ||
33 | <source>People</source> | ||
34 | <target>undefined</target> | ||
35 | </trans-unit> | ||
36 | <trans-unit id="Comedy"> | ||
37 | <source>Comedy</source> | ||
38 | <target>undefined</target> | ||
39 | </trans-unit> | ||
40 | <trans-unit id="Entertainment"> | ||
41 | <source>Entertainment</source> | ||
42 | <target>undefined</target> | ||
43 | </trans-unit> | ||
44 | <trans-unit id="News"> | ||
45 | <source>News</source> | ||
46 | <target>undefined</target> | ||
47 | </trans-unit> | ||
48 | <trans-unit id="How To"> | ||
49 | <source>How To</source> | ||
50 | <target>undefined</target> | ||
51 | </trans-unit> | ||
52 | <trans-unit id="Education"> | ||
53 | <source>Education</source> | ||
54 | <target>undefined</target> | ||
55 | </trans-unit> | ||
56 | <trans-unit id="Activism"> | ||
57 | <source>Activism</source> | ||
58 | <target>undefined</target> | ||
59 | </trans-unit> | ||
60 | <trans-unit id="Science & Technology"> | ||
61 | <source>Science & Technology</source> | ||
62 | <target>undefined</target> | ||
63 | </trans-unit> | ||
64 | <trans-unit id="Animals"> | ||
65 | <source>Animals</source> | ||
66 | <target>undefined</target> | ||
67 | </trans-unit> | ||
68 | <trans-unit id="Kids"> | ||
69 | <source>Kids</source> | ||
70 | <target>undefined</target> | ||
71 | </trans-unit> | ||
72 | <trans-unit id="Food"> | ||
73 | <source>Food</source> | ||
74 | <target>undefined</target> | ||
75 | </trans-unit> | ||
76 | <trans-unit id="Attribution"> | ||
77 | <source>Attribution</source> | ||
78 | <target>undefined</target> | ||
79 | </trans-unit> | ||
80 | <trans-unit id="Attribution - Share Alike"> | ||
81 | <source>Attribution - Share Alike</source> | ||
82 | <target>undefined</target> | ||
83 | </trans-unit> | ||
84 | <trans-unit id="Attribution - No Derivatives"> | ||
85 | <source>Attribution - No Derivatives</source> | ||
86 | <target>undefined</target> | ||
87 | </trans-unit> | ||
88 | <trans-unit id="Attribution - Non Commercial"> | ||
89 | <source>Attribution - Non Commercial</source> | ||
90 | <target>undefined</target> | ||
91 | </trans-unit> | ||
92 | <trans-unit id="Attribution - Non Commercial - Share Alike"> | ||
93 | <source>Attribution - Non Commercial - Share Alike</source> | ||
94 | <target>undefined</target> | ||
95 | </trans-unit> | ||
96 | <trans-unit id="Attribution - Non Commercial - No Derivatives"> | ||
97 | <source>Attribution - Non Commercial - No Derivatives</source> | ||
98 | <target>undefined</target> | ||
99 | </trans-unit> | ||
100 | <trans-unit id="Public Domain Dedication"> | ||
101 | <source>Public Domain Dedication</source> | ||
102 | <target>undefined</target> | ||
103 | </trans-unit> | ||
104 | <trans-unit id="Public"> | ||
105 | <source>Public</source> | ||
106 | <target>undefined</target> | ||
107 | </trans-unit> | ||
108 | <trans-unit id="Unlisted"> | ||
109 | <source>Unlisted</source> | ||
110 | <target>undefined</target> | ||
111 | </trans-unit> | ||
112 | <trans-unit id="Private"> | ||
113 | <source>Private</source> | ||
114 | <target>undefined</target> | ||
115 | </trans-unit> | ||
116 | <trans-unit id="Afar"> | ||
117 | <source>Afar</source> | ||
118 | <target>undefined</target> | ||
119 | </trans-unit> | ||
120 | <trans-unit id="Abkhazian"> | ||
121 | <source>Abkhazian</source> | ||
122 | <target>undefined</target> | ||
123 | </trans-unit> | ||
124 | <trans-unit id="Afrikaans"> | ||
125 | <source>Afrikaans</source> | ||
126 | <target>undefined</target> | ||
127 | </trans-unit> | ||
128 | <trans-unit id="Akan"> | ||
129 | <source>Akan</source> | ||
130 | <target>undefined</target> | ||
131 | </trans-unit> | ||
132 | <trans-unit id="Amharic"> | ||
133 | <source>Amharic</source> | ||
134 | <target>undefined</target> | ||
135 | </trans-unit> | ||
136 | <trans-unit id="Arabic"> | ||
137 | <source>Arabic</source> | ||
138 | <target>undefined</target> | ||
139 | </trans-unit> | ||
140 | <trans-unit id="Aragonese"> | ||
141 | <source>Aragonese</source> | ||
142 | <target>undefined</target> | ||
143 | </trans-unit> | ||
144 | <trans-unit id="American Sign Language"> | ||
145 | <source>American Sign Language</source> | ||
146 | <target>undefined</target> | ||
147 | </trans-unit> | ||
148 | <trans-unit id="Assamese"> | ||
149 | <source>Assamese</source> | ||
150 | <target>undefined</target> | ||
151 | </trans-unit> | ||
152 | <trans-unit id="Avaric"> | ||
153 | <source>Avaric</source> | ||
154 | <target>undefined</target> | ||
155 | </trans-unit> | ||
156 | <trans-unit id="Aymara"> | ||
157 | <source>Aymara</source> | ||
158 | <target>undefined</target> | ||
159 | </trans-unit> | ||
160 | <trans-unit id="Azerbaijani"> | ||
161 | <source>Azerbaijani</source> | ||
162 | <target>undefined</target> | ||
163 | </trans-unit> | ||
164 | <trans-unit id="Bashkir"> | ||
165 | <source>Bashkir</source> | ||
166 | <target>undefined</target> | ||
167 | </trans-unit> | ||
168 | <trans-unit id="Bambara"> | ||
169 | <source>Bambara</source> | ||
170 | <target>undefined</target> | ||
171 | </trans-unit> | ||
172 | <trans-unit id="Belarusian"> | ||
173 | <source>Belarusian</source> | ||
174 | <target>undefined</target> | ||
175 | </trans-unit> | ||
176 | <trans-unit id="Bengali"> | ||
177 | <source>Bengali</source> | ||
178 | <target>undefined</target> | ||
179 | </trans-unit> | ||
180 | <trans-unit id="British Sign Language"> | ||
181 | <source>British Sign Language</source> | ||
182 | <target>undefined</target> | ||
183 | </trans-unit> | ||
184 | <trans-unit id="Bislama"> | ||
185 | <source>Bislama</source> | ||
186 | <target>undefined</target> | ||
187 | </trans-unit> | ||
188 | <trans-unit id="Tibetan"> | ||
189 | <source>Tibetan</source> | ||
190 | <target>undefined</target> | ||
191 | </trans-unit> | ||
192 | <trans-unit id="Bosnian"> | ||
193 | <source>Bosnian</source> | ||
194 | <target>undefined</target> | ||
195 | </trans-unit> | ||
196 | <trans-unit id="Breton"> | ||
197 | <source>Breton</source> | ||
198 | <target>undefined</target> | ||
199 | </trans-unit> | ||
200 | <trans-unit id="Bulgarian"> | ||
201 | <source>Bulgarian</source> | ||
202 | <target>undefined</target> | ||
203 | </trans-unit> | ||
204 | <trans-unit id="Brazilian Sign Language"> | ||
205 | <source>Brazilian Sign Language</source> | ||
206 | <target>undefined</target> | ||
207 | </trans-unit> | ||
208 | <trans-unit id="Catalan"> | ||
209 | <source>Catalan</source> | ||
210 | <target>undefined</target> | ||
211 | </trans-unit> | ||
212 | <trans-unit id="Czech"> | ||
213 | <source>Czech</source> | ||
214 | <target>undefined</target> | ||
215 | </trans-unit> | ||
216 | <trans-unit id="Chamorro"> | ||
217 | <source>Chamorro</source> | ||
218 | <target>undefined</target> | ||
219 | </trans-unit> | ||
220 | <trans-unit id="Chechen"> | ||
221 | <source>Chechen</source> | ||
222 | <target>undefined</target> | ||
223 | </trans-unit> | ||
224 | <trans-unit id="Chuvash"> | ||
225 | <source>Chuvash</source> | ||
226 | <target>undefined</target> | ||
227 | </trans-unit> | ||
228 | <trans-unit id="Cornish"> | ||
229 | <source>Cornish</source> | ||
230 | <target>undefined</target> | ||
231 | </trans-unit> | ||
232 | <trans-unit id="Corsican"> | ||
233 | <source>Corsican</source> | ||
234 | <target>undefined</target> | ||
235 | </trans-unit> | ||
236 | <trans-unit id="Cree"> | ||
237 | <source>Cree</source> | ||
238 | <target>undefined</target> | ||
239 | </trans-unit> | ||
240 | <trans-unit id="Czech Sign Language"> | ||
241 | <source>Czech Sign Language</source> | ||
242 | <target>undefined</target> | ||
243 | </trans-unit> | ||
244 | <trans-unit id="Chinese Sign Language"> | ||
245 | <source>Chinese Sign Language</source> | ||
246 | <target>undefined</target> | ||
247 | </trans-unit> | ||
248 | <trans-unit id="Welsh"> | ||
249 | <source>Welsh</source> | ||
250 | <target>undefined</target> | ||
251 | </trans-unit> | ||
252 | <trans-unit id="Danish"> | ||
253 | <source>Danish</source> | ||
254 | <target>undefined</target> | ||
255 | </trans-unit> | ||
256 | <trans-unit id="German"> | ||
257 | <source>German</source> | ||
258 | <target>undefined</target> | ||
259 | </trans-unit> | ||
260 | <trans-unit id="Dhivehi"> | ||
261 | <source>Dhivehi</source> | ||
262 | <target>undefined</target> | ||
263 | </trans-unit> | ||
264 | <trans-unit id="Danish Sign Language"> | ||
265 | <source>Danish Sign Language</source> | ||
266 | <target>undefined</target> | ||
267 | </trans-unit> | ||
268 | <trans-unit id="Dzongkha"> | ||
269 | <source>Dzongkha</source> | ||
270 | <target>undefined</target> | ||
271 | </trans-unit> | ||
272 | <trans-unit id="Modern Greek (1453-)"> | ||
273 | <source>Modern Greek (1453-)</source> | ||
274 | <target>undefined</target> | ||
275 | </trans-unit> | ||
276 | <trans-unit id="English"> | ||
277 | <source>English</source> | ||
278 | <target>undefined</target> | ||
279 | </trans-unit> | ||
280 | <trans-unit id="Estonian"> | ||
281 | <source>Estonian</source> | ||
282 | <target>undefined</target> | ||
283 | </trans-unit> | ||
284 | <trans-unit id="Basque"> | ||
285 | <source>Basque</source> | ||
286 | <target>undefined</target> | ||
287 | </trans-unit> | ||
288 | <trans-unit id="Ewe"> | ||
289 | <source>Ewe</source> | ||
290 | <target>undefined</target> | ||
291 | </trans-unit> | ||
292 | <trans-unit id="Faroese"> | ||
293 | <source>Faroese</source> | ||
294 | <target>undefined</target> | ||
295 | </trans-unit> | ||
296 | <trans-unit id="Persian"> | ||
297 | <source>Persian</source> | ||
298 | <target>undefined</target> | ||
299 | </trans-unit> | ||
300 | <trans-unit id="Fijian"> | ||
301 | <source>Fijian</source> | ||
302 | <target>undefined</target> | ||
303 | </trans-unit> | ||
304 | <trans-unit id="Finnish"> | ||
305 | <source>Finnish</source> | ||
306 | <target>undefined</target> | ||
307 | </trans-unit> | ||
308 | <trans-unit id="French"> | ||
309 | <source>French</source> | ||
310 | <target>undefined</target> | ||
311 | </trans-unit> | ||
312 | <trans-unit id="Western Frisian"> | ||
313 | <source>Western Frisian</source> | ||
314 | <target>undefined</target> | ||
315 | </trans-unit> | ||
316 | <trans-unit id="French Sign Language"> | ||
317 | <source>French Sign Language</source> | ||
318 | <target>undefined</target> | ||
319 | </trans-unit> | ||
320 | <trans-unit id="Fulah"> | ||
321 | <source>Fulah</source> | ||
322 | <target>undefined</target> | ||
323 | </trans-unit> | ||
324 | <trans-unit id="Scottish Gaelic"> | ||
325 | <source>Scottish Gaelic</source> | ||
326 | <target>undefined</target> | ||
327 | </trans-unit> | ||
328 | <trans-unit id="Irish"> | ||
329 | <source>Irish</source> | ||
330 | <target>undefined</target> | ||
331 | </trans-unit> | ||
332 | <trans-unit id="Galician"> | ||
333 | <source>Galician</source> | ||
334 | <target>undefined</target> | ||
335 | </trans-unit> | ||
336 | <trans-unit id="Manx"> | ||
337 | <source>Manx</source> | ||
338 | <target>undefined</target> | ||
339 | </trans-unit> | ||
340 | <trans-unit id="Guarani"> | ||
341 | <source>Guarani</source> | ||
342 | <target>undefined</target> | ||
343 | </trans-unit> | ||
344 | <trans-unit id="German Sign Language"> | ||
345 | <source>German Sign Language</source> | ||
346 | <target>undefined</target> | ||
347 | </trans-unit> | ||
348 | <trans-unit id="Gujarati"> | ||
349 | <source>Gujarati</source> | ||
350 | <target>undefined</target> | ||
351 | </trans-unit> | ||
352 | <trans-unit id="Haitian"> | ||
353 | <source>Haitian</source> | ||
354 | <target>undefined</target> | ||
355 | </trans-unit> | ||
356 | <trans-unit id="Hausa"> | ||
357 | <source>Hausa</source> | ||
358 | <target>undefined</target> | ||
359 | </trans-unit> | ||
360 | <trans-unit id="Serbo-Croatian"> | ||
361 | <source>Serbo-Croatian</source> | ||
362 | <target>undefined</target> | ||
363 | </trans-unit> | ||
364 | <trans-unit id="Hebrew"> | ||
365 | <source>Hebrew</source> | ||
366 | <target>undefined</target> | ||
367 | </trans-unit> | ||
368 | <trans-unit id="Herero"> | ||
369 | <source>Herero</source> | ||
370 | <target>undefined</target> | ||
371 | </trans-unit> | ||
372 | <trans-unit id="Hindi"> | ||
373 | <source>Hindi</source> | ||
374 | <target>undefined</target> | ||
375 | </trans-unit> | ||
376 | <trans-unit id="Hiri Motu"> | ||
377 | <source>Hiri Motu</source> | ||
378 | <target>undefined</target> | ||
379 | </trans-unit> | ||
380 | <trans-unit id="Croatian"> | ||
381 | <source>Croatian</source> | ||
382 | <target>undefined</target> | ||
383 | </trans-unit> | ||
384 | <trans-unit id="Hungarian"> | ||
385 | <source>Hungarian</source> | ||
386 | <target>undefined</target> | ||
387 | </trans-unit> | ||
388 | <trans-unit id="Armenian"> | ||
389 | <source>Armenian</source> | ||
390 | <target>undefined</target> | ||
391 | </trans-unit> | ||
392 | <trans-unit id="Igbo"> | ||
393 | <source>Igbo</source> | ||
394 | <target>undefined</target> | ||
395 | </trans-unit> | ||
396 | <trans-unit id="Sichuan Yi"> | ||
397 | <source>Sichuan Yi</source> | ||
398 | <target>undefined</target> | ||
399 | </trans-unit> | ||
400 | <trans-unit id="Inuktitut"> | ||
401 | <source>Inuktitut</source> | ||
402 | <target>undefined</target> | ||
403 | </trans-unit> | ||
404 | <trans-unit id="Indonesian"> | ||
405 | <source>Indonesian</source> | ||
406 | <target>undefined</target> | ||
407 | </trans-unit> | ||
408 | <trans-unit id="Inupiaq"> | ||
409 | <source>Inupiaq</source> | ||
410 | <target>undefined</target> | ||
411 | </trans-unit> | ||
412 | <trans-unit id="Icelandic"> | ||
413 | <source>Icelandic</source> | ||
414 | <target>undefined</target> | ||
415 | </trans-unit> | ||
416 | <trans-unit id="Italian"> | ||
417 | <source>Italian</source> | ||
418 | <target>undefined</target> | ||
419 | </trans-unit> | ||
420 | <trans-unit id="Javanese"> | ||
421 | <source>Javanese</source> | ||
422 | <target>undefined</target> | ||
423 | </trans-unit> | ||
424 | <trans-unit id="Japanese"> | ||
425 | <source>Japanese</source> | ||
426 | <target>undefined</target> | ||
427 | </trans-unit> | ||
428 | <trans-unit id="Japanese Sign Language"> | ||
429 | <source>Japanese Sign Language</source> | ||
430 | <target>undefined</target> | ||
431 | </trans-unit> | ||
432 | <trans-unit id="Kalaallisut"> | ||
433 | <source>Kalaallisut</source> | ||
434 | <target>undefined</target> | ||
435 | </trans-unit> | ||
436 | <trans-unit id="Kannada"> | ||
437 | <source>Kannada</source> | ||
438 | <target>undefined</target> | ||
439 | </trans-unit> | ||
440 | <trans-unit id="Kashmiri"> | ||
441 | <source>Kashmiri</source> | ||
442 | <target>undefined</target> | ||
443 | </trans-unit> | ||
444 | <trans-unit id="Georgian"> | ||
445 | <source>Georgian</source> | ||
446 | <target>undefined</target> | ||
447 | </trans-unit> | ||
448 | <trans-unit id="Kanuri"> | ||
449 | <source>Kanuri</source> | ||
450 | <target>undefined</target> | ||
451 | </trans-unit> | ||
452 | <trans-unit id="Kazakh"> | ||
453 | <source>Kazakh</source> | ||
454 | <target>undefined</target> | ||
455 | </trans-unit> | ||
456 | <trans-unit id="Khmer"> | ||
457 | <source>Khmer</source> | ||
458 | <target>undefined</target> | ||
459 | </trans-unit> | ||
460 | <trans-unit id="Kikuyu"> | ||
461 | <source>Kikuyu</source> | ||
462 | <target>undefined</target> | ||
463 | </trans-unit> | ||
464 | <trans-unit id="Kinyarwanda"> | ||
465 | <source>Kinyarwanda</source> | ||
466 | <target>undefined</target> | ||
467 | </trans-unit> | ||
468 | <trans-unit id="Kirghiz"> | ||
469 | <source>Kirghiz</source> | ||
470 | <target>undefined</target> | ||
471 | </trans-unit> | ||
472 | <trans-unit id="Komi"> | ||
473 | <source>Komi</source> | ||
474 | <target>undefined</target> | ||
475 | </trans-unit> | ||
476 | <trans-unit id="Kongo"> | ||
477 | <source>Kongo</source> | ||
478 | <target>undefined</target> | ||
479 | </trans-unit> | ||
480 | <trans-unit id="Korean"> | ||
481 | <source>Korean</source> | ||
482 | <target>undefined</target> | ||
483 | </trans-unit> | ||
484 | <trans-unit id="Kuanyama"> | ||
485 | <source>Kuanyama</source> | ||
486 | <target>undefined</target> | ||
487 | </trans-unit> | ||
488 | <trans-unit id="Kurdish"> | ||
489 | <source>Kurdish</source> | ||
490 | <target>undefined</target> | ||
491 | </trans-unit> | ||
492 | <trans-unit id="Lao"> | ||
493 | <source>Lao</source> | ||
494 | <target>undefined</target> | ||
495 | </trans-unit> | ||
496 | <trans-unit id="Latvian"> | ||
497 | <source>Latvian</source> | ||
498 | <target>undefined</target> | ||
499 | </trans-unit> | ||
500 | <trans-unit id="Limburgan"> | ||
501 | <source>Limburgan</source> | ||
502 | <target>undefined</target> | ||
503 | </trans-unit> | ||
504 | <trans-unit id="Lingala"> | ||
505 | <source>Lingala</source> | ||
506 | <target>undefined</target> | ||
507 | </trans-unit> | ||
508 | <trans-unit id="Lithuanian"> | ||
509 | <source>Lithuanian</source> | ||
510 | <target>undefined</target> | ||
511 | </trans-unit> | ||
512 | <trans-unit id="Luxembourgish"> | ||
513 | <source>Luxembourgish</source> | ||
514 | <target>undefined</target> | ||
515 | </trans-unit> | ||
516 | <trans-unit id="Luba-Katanga"> | ||
517 | <source>Luba-Katanga</source> | ||
518 | <target>undefined</target> | ||
519 | </trans-unit> | ||
520 | <trans-unit id="Ganda"> | ||
521 | <source>Ganda</source> | ||
522 | <target>undefined</target> | ||
523 | </trans-unit> | ||
524 | <trans-unit id="Marshallese"> | ||
525 | <source>Marshallese</source> | ||
526 | <target>undefined</target> | ||
527 | </trans-unit> | ||
528 | <trans-unit id="Malayalam"> | ||
529 | <source>Malayalam</source> | ||
530 | <target>undefined</target> | ||
531 | </trans-unit> | ||
532 | <trans-unit id="Marathi"> | ||
533 | <source>Marathi</source> | ||
534 | <target>undefined</target> | ||
535 | </trans-unit> | ||
536 | <trans-unit id="Macedonian"> | ||
537 | <source>Macedonian</source> | ||
538 | <target>undefined</target> | ||
539 | </trans-unit> | ||
540 | <trans-unit id="Malagasy"> | ||
541 | <source>Malagasy</source> | ||
542 | <target>undefined</target> | ||
543 | </trans-unit> | ||
544 | <trans-unit id="Maltese"> | ||
545 | <source>Maltese</source> | ||
546 | <target>undefined</target> | ||
547 | </trans-unit> | ||
548 | <trans-unit id="Mongolian"> | ||
549 | <source>Mongolian</source> | ||
550 | <target>undefined</target> | ||
551 | </trans-unit> | ||
552 | <trans-unit id="Maori"> | ||
553 | <source>Maori</source> | ||
554 | <target>undefined</target> | ||
555 | </trans-unit> | ||
556 | <trans-unit id="Malay (macrolanguage)"> | ||
557 | <source>Malay (macrolanguage)</source> | ||
558 | <target>undefined</target> | ||
559 | </trans-unit> | ||
560 | <trans-unit id="Burmese"> | ||
561 | <source>Burmese</source> | ||
562 | <target>undefined</target> | ||
563 | </trans-unit> | ||
564 | <trans-unit id="Nauru"> | ||
565 | <source>Nauru</source> | ||
566 | <target>undefined</target> | ||
567 | </trans-unit> | ||
568 | <trans-unit id="Navajo"> | ||
569 | <source>Navajo</source> | ||
570 | <target>undefined</target> | ||
571 | </trans-unit> | ||
572 | <trans-unit id="South Ndebele"> | ||
573 | <source>South Ndebele</source> | ||
574 | <target>undefined</target> | ||
575 | </trans-unit> | ||
576 | <trans-unit id="North Ndebele"> | ||
577 | <source>North Ndebele</source> | ||
578 | <target>undefined</target> | ||
579 | </trans-unit> | ||
580 | <trans-unit id="Ndonga"> | ||
581 | <source>Ndonga</source> | ||
582 | <target>undefined</target> | ||
583 | </trans-unit> | ||
584 | <trans-unit id="Nepali (macrolanguage)"> | ||
585 | <source>Nepali (macrolanguage)</source> | ||
586 | <target>undefined</target> | ||
587 | </trans-unit> | ||
588 | <trans-unit id="Dutch"> | ||
589 | <source>Dutch</source> | ||
590 | <target>undefined</target> | ||
591 | </trans-unit> | ||
592 | <trans-unit id="Norwegian Nynorsk"> | ||
593 | <source>Norwegian Nynorsk</source> | ||
594 | <target>undefined</target> | ||
595 | </trans-unit> | ||
596 | <trans-unit id="Norwegian Bokmål"> | ||
597 | <source>Norwegian Bokmål</source> | ||
598 | <target>undefined</target> | ||
599 | </trans-unit> | ||
600 | <trans-unit id="Norwegian"> | ||
601 | <source>Norwegian</source> | ||
602 | <target>undefined</target> | ||
603 | </trans-unit> | ||
604 | <trans-unit id="Nyanja"> | ||
605 | <source>Nyanja</source> | ||
606 | <target>undefined</target> | ||
607 | </trans-unit> | ||
608 | <trans-unit id="Occitan (post 1500)"> | ||
609 | <source>Occitan (post 1500)</source> | ||
610 | <target>undefined</target> | ||
611 | </trans-unit> | ||
612 | <trans-unit id="Ojibwa"> | ||
613 | <source>Ojibwa</source> | ||
614 | <target>undefined</target> | ||
615 | </trans-unit> | ||
616 | <trans-unit id="Oriya (macrolanguage)"> | ||
617 | <source>Oriya (macrolanguage)</source> | ||
618 | <target>undefined</target> | ||
619 | </trans-unit> | ||
620 | <trans-unit id="Oromo"> | ||
621 | <source>Oromo</source> | ||
622 | <target>undefined</target> | ||
623 | </trans-unit> | ||
624 | <trans-unit id="Ossetian"> | ||
625 | <source>Ossetian</source> | ||
626 | <target>undefined</target> | ||
627 | </trans-unit> | ||
628 | <trans-unit id="Panjabi"> | ||
629 | <source>Panjabi</source> | ||
630 | <target>undefined</target> | ||
631 | </trans-unit> | ||
632 | <trans-unit id="Pakistan Sign Language"> | ||
633 | <source>Pakistan Sign Language</source> | ||
634 | <target>undefined</target> | ||
635 | </trans-unit> | ||
636 | <trans-unit id="Polish"> | ||
637 | <source>Polish</source> | ||
638 | <target>undefined</target> | ||
639 | </trans-unit> | ||
640 | <trans-unit id="Portuguese"> | ||
641 | <source>Portuguese</source> | ||
642 | <target>undefined</target> | ||
643 | </trans-unit> | ||
644 | <trans-unit id="Pushto"> | ||
645 | <source>Pushto</source> | ||
646 | <target>undefined</target> | ||
647 | </trans-unit> | ||
648 | <trans-unit id="Quechua"> | ||
649 | <source>Quechua</source> | ||
650 | <target>undefined</target> | ||
651 | </trans-unit> | ||
652 | <trans-unit id="Romansh"> | ||
653 | <source>Romansh</source> | ||
654 | <target>undefined</target> | ||
655 | </trans-unit> | ||
656 | <trans-unit id="Romanian"> | ||
657 | <source>Romanian</source> | ||
658 | <target>undefined</target> | ||
659 | </trans-unit> | ||
660 | <trans-unit id="Russian Sign Language"> | ||
661 | <source>Russian Sign Language</source> | ||
662 | <target>undefined</target> | ||
663 | </trans-unit> | ||
664 | <trans-unit id="Rundi"> | ||
665 | <source>Rundi</source> | ||
666 | <target>undefined</target> | ||
667 | </trans-unit> | ||
668 | <trans-unit id="Russian"> | ||
669 | <source>Russian</source> | ||
670 | <target>undefined</target> | ||
671 | </trans-unit> | ||
672 | <trans-unit id="Sango"> | ||
673 | <source>Sango</source> | ||
674 | <target>undefined</target> | ||
675 | </trans-unit> | ||
676 | <trans-unit id="Saudi Arabian Sign Language"> | ||
677 | <source>Saudi Arabian Sign Language</source> | ||
678 | <target>undefined</target> | ||
679 | </trans-unit> | ||
680 | <trans-unit id="South African Sign Language"> | ||
681 | <source>South African Sign Language</source> | ||
682 | <target>undefined</target> | ||
683 | </trans-unit> | ||
684 | <trans-unit id="Sinhala"> | ||
685 | <source>Sinhala</source> | ||
686 | <target>undefined</target> | ||
687 | </trans-unit> | ||
688 | <trans-unit id="Slovak"> | ||
689 | <source>Slovak</source> | ||
690 | <target>undefined</target> | ||
691 | </trans-unit> | ||
692 | <trans-unit id="Slovenian"> | ||
693 | <source>Slovenian</source> | ||
694 | <target>undefined</target> | ||
695 | </trans-unit> | ||
696 | <trans-unit id="Northern Sami"> | ||
697 | <source>Northern Sami</source> | ||
698 | <target>undefined</target> | ||
699 | </trans-unit> | ||
700 | <trans-unit id="Samoan"> | ||
701 | <source>Samoan</source> | ||
702 | <target>undefined</target> | ||
703 | </trans-unit> | ||
704 | <trans-unit id="Shona"> | ||
705 | <source>Shona</source> | ||
706 | <target>undefined</target> | ||
707 | </trans-unit> | ||
708 | <trans-unit id="Sindhi"> | ||
709 | <source>Sindhi</source> | ||
710 | <target>undefined</target> | ||
711 | </trans-unit> | ||
712 | <trans-unit id="Somali"> | ||
713 | <source>Somali</source> | ||
714 | <target>undefined</target> | ||
715 | </trans-unit> | ||
716 | <trans-unit id="Southern Sotho"> | ||
717 | <source>Southern Sotho</source> | ||
718 | <target>undefined</target> | ||
719 | </trans-unit> | ||
720 | <trans-unit id="Spanish"> | ||
721 | <source>Spanish</source> | ||
722 | <target>undefined</target> | ||
723 | </trans-unit> | ||
724 | <trans-unit id="Albanian"> | ||
725 | <source>Albanian</source> | ||
726 | <target>undefined</target> | ||
727 | </trans-unit> | ||
728 | <trans-unit id="Sardinian"> | ||
729 | <source>Sardinian</source> | ||
730 | <target>undefined</target> | ||
731 | </trans-unit> | ||
732 | <trans-unit id="Serbian"> | ||
733 | <source>Serbian</source> | ||
734 | <target>undefined</target> | ||
735 | </trans-unit> | ||
736 | <trans-unit id="Swati"> | ||
737 | <source>Swati</source> | ||
738 | <target>undefined</target> | ||
739 | </trans-unit> | ||
740 | <trans-unit id="Sundanese"> | ||
741 | <source>Sundanese</source> | ||
742 | <target>undefined</target> | ||
743 | </trans-unit> | ||
744 | <trans-unit id="Swahili (macrolanguage)"> | ||
745 | <source>Swahili (macrolanguage)</source> | ||
746 | <target>undefined</target> | ||
747 | </trans-unit> | ||
748 | <trans-unit id="Swedish"> | ||
749 | <source>Swedish</source> | ||
750 | <target>undefined</target> | ||
751 | </trans-unit> | ||
752 | <trans-unit id="Swedish Sign Language"> | ||
753 | <source>Swedish Sign Language</source> | ||
754 | <target>undefined</target> | ||
755 | </trans-unit> | ||
756 | <trans-unit id="Tahitian"> | ||
757 | <source>Tahitian</source> | ||
758 | <target>undefined</target> | ||
759 | </trans-unit> | ||
760 | <trans-unit id="Tamil"> | ||
761 | <source>Tamil</source> | ||
762 | <target>undefined</target> | ||
763 | </trans-unit> | ||
764 | <trans-unit id="Tatar"> | ||
765 | <source>Tatar</source> | ||
766 | <target>undefined</target> | ||
767 | </trans-unit> | ||
768 | <trans-unit id="Telugu"> | ||
769 | <source>Telugu</source> | ||
770 | <target>undefined</target> | ||
771 | </trans-unit> | ||
772 | <trans-unit id="Tajik"> | ||
773 | <source>Tajik</source> | ||
774 | <target>undefined</target> | ||
775 | </trans-unit> | ||
776 | <trans-unit id="Tagalog"> | ||
777 | <source>Tagalog</source> | ||
778 | <target>undefined</target> | ||
779 | </trans-unit> | ||
780 | <trans-unit id="Thai"> | ||
781 | <source>Thai</source> | ||
782 | <target>undefined</target> | ||
783 | </trans-unit> | ||
784 | <trans-unit id="Tigrinya"> | ||
785 | <source>Tigrinya</source> | ||
786 | <target>undefined</target> | ||
787 | </trans-unit> | ||
788 | <trans-unit id="Tonga (Tonga Islands)"> | ||
789 | <source>Tonga (Tonga Islands)</source> | ||
790 | <target>undefined</target> | ||
791 | </trans-unit> | ||
792 | <trans-unit id="Tswana"> | ||
793 | <source>Tswana</source> | ||
794 | <target>undefined</target> | ||
795 | </trans-unit> | ||
796 | <trans-unit id="Tsonga"> | ||
797 | <source>Tsonga</source> | ||
798 | <target>undefined</target> | ||
799 | </trans-unit> | ||
800 | <trans-unit id="Turkmen"> | ||
801 | <source>Turkmen</source> | ||
802 | <target>undefined</target> | ||
803 | </trans-unit> | ||
804 | <trans-unit id="Turkish"> | ||
805 | <source>Turkish</source> | ||
806 | <target>undefined</target> | ||
807 | </trans-unit> | ||
808 | <trans-unit id="Twi"> | ||
809 | <source>Twi</source> | ||
810 | <target>undefined</target> | ||
811 | </trans-unit> | ||
812 | <trans-unit id="Uighur"> | ||
813 | <source>Uighur</source> | ||
814 | <target>undefined</target> | ||
815 | </trans-unit> | ||
816 | <trans-unit id="Ukrainian"> | ||
817 | <source>Ukrainian</source> | ||
818 | <target>undefined</target> | ||
819 | </trans-unit> | ||
820 | <trans-unit id="Urdu"> | ||
821 | <source>Urdu</source> | ||
822 | <target>undefined</target> | ||
823 | </trans-unit> | ||
824 | <trans-unit id="Uzbek"> | ||
825 | <source>Uzbek</source> | ||
826 | <target>undefined</target> | ||
827 | </trans-unit> | ||
828 | <trans-unit id="Venda"> | ||
829 | <source>Venda</source> | ||
830 | <target>undefined</target> | ||
831 | </trans-unit> | ||
832 | <trans-unit id="Vietnamese"> | ||
833 | <source>Vietnamese</source> | ||
834 | <target>undefined</target> | ||
835 | </trans-unit> | ||
836 | <trans-unit id="Walloon"> | ||
837 | <source>Walloon</source> | ||
838 | <target>undefined</target> | ||
839 | </trans-unit> | ||
840 | <trans-unit id="Wolof"> | ||
841 | <source>Wolof</source> | ||
842 | <target>undefined</target> | ||
843 | </trans-unit> | ||
844 | <trans-unit id="Xhosa"> | ||
845 | <source>Xhosa</source> | ||
846 | <target>undefined</target> | ||
847 | </trans-unit> | ||
848 | <trans-unit id="Yiddish"> | ||
849 | <source>Yiddish</source> | ||
850 | <target>undefined</target> | ||
851 | </trans-unit> | ||
852 | <trans-unit id="Yoruba"> | ||
853 | <source>Yoruba</source> | ||
854 | <target>undefined</target> | ||
855 | </trans-unit> | ||
856 | <trans-unit id="Zhuang"> | ||
857 | <source>Zhuang</source> | ||
858 | <target>undefined</target> | ||
859 | </trans-unit> | ||
860 | <trans-unit id="Chinese"> | ||
861 | <source>Chinese</source> | ||
862 | <target>undefined</target> | ||
863 | </trans-unit> | ||
864 | <trans-unit id="Zulu"> | ||
865 | <source>Zulu</source> | ||
866 | <target>undefined</target> | ||
867 | </trans-unit> | ||
868 | <trans-unit id="Misc"> | ||
869 | <source>Misc</source> | ||
870 | <target>undefined</target> | ||
871 | </trans-unit> | ||
872 | <trans-unit id="Unknown"> | ||
873 | <source>Unknown</source> | ||
874 | <target>undefined</target> | ||
875 | </trans-unit> | ||
876 | </body> | ||
877 | </file> | ||
878 | </xliff> \ No newline at end of file | ||
diff --git a/client/src/locale/target/player_fr.xml b/client/src/locale/target/player_fr.xml deleted file mode 100644 index eafa4baff..000000000 --- a/client/src/locale/target/player_fr.xml +++ /dev/null | |||
@@ -1,379 +0,0 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | ||
2 | <!--XLIFF document generated by Zanata. Visit http://zanata.org for more infomation.--> | ||
3 | <xliff xmlns="urn:oasis:names:tc:xliff:document:1.1" xmlns:xyz="urn:appInfo:Items" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.1 http://www.oasis-open.org/committees/xliff/documents/xliff-core-1.1.xsd" version="1.1"> | ||
4 | <file source-language="en-US" datatype="plaintext" original="" target-language="fr"> | ||
5 | <body> | ||
6 | <trans-unit id="Audio Player"> | ||
7 | <source>Audio Player</source> | ||
8 | <target>Lecteur audio</target> | ||
9 | </trans-unit> | ||
10 | <trans-unit id="Video Player"> | ||
11 | <source>Video Player</source> | ||
12 | <target>Lecteur vidéo</target> | ||
13 | </trans-unit> | ||
14 | <trans-unit id="Play"> | ||
15 | <source>Play</source> | ||
16 | <target>Lecture</target> | ||
17 | </trans-unit> | ||
18 | <trans-unit id="Pause"> | ||
19 | <source>Pause</source> | ||
20 | <target>Pause</target> | ||
21 | </trans-unit> | ||
22 | <trans-unit id="Replay"> | ||
23 | <source>Replay</source> | ||
24 | <target>Revoir</target> | ||
25 | </trans-unit> | ||
26 | <trans-unit id="Current Time"> | ||
27 | <source>Current Time</source> | ||
28 | <target>Temps actuel</target> | ||
29 | </trans-unit> | ||
30 | <trans-unit id="Duration"> | ||
31 | <source>Duration</source> | ||
32 | <target>Durée</target> | ||
33 | </trans-unit> | ||
34 | <trans-unit id="Remaining Time"> | ||
35 | <source>Remaining Time</source> | ||
36 | <target>Temps restant</target> | ||
37 | </trans-unit> | ||
38 | <trans-unit id="Stream Type"> | ||
39 | <source>Stream Type</source> | ||
40 | <target>Type de flux</target> | ||
41 | </trans-unit> | ||
42 | <trans-unit id="LIVE"> | ||
43 | <source>LIVE</source> | ||
44 | <target>EN DIRECT</target> | ||
45 | </trans-unit> | ||
46 | <trans-unit id="Loaded"> | ||
47 | <source>Loaded</source> | ||
48 | <target>Chargé</target> | ||
49 | </trans-unit> | ||
50 | <trans-unit id="Progress"> | ||
51 | <source>Progress</source> | ||
52 | <target>Progression</target> | ||
53 | </trans-unit> | ||
54 | <trans-unit id="Progress Bar"> | ||
55 | <source>Progress Bar</source> | ||
56 | <target>Barre de progression</target> | ||
57 | </trans-unit> | ||
58 | <trans-unit id="progress bar timing: currentTime={1} duration={2}"> | ||
59 | <source>{1} of {2}</source> | ||
60 | <target>{1} de {2}</target> | ||
61 | </trans-unit> | ||
62 | <trans-unit id="Fullscreen"> | ||
63 | <source>Fullscreen</source> | ||
64 | <target>Plein écran</target> | ||
65 | </trans-unit> | ||
66 | <trans-unit id="Non-Fullscreen"> | ||
67 | <source>Non-Fullscreen</source> | ||
68 | <target>Fenêtré</target> | ||
69 | </trans-unit> | ||
70 | <trans-unit id="Mute"> | ||
71 | <source>Mute</source> | ||
72 | <target>Sourdine</target> | ||
73 | </trans-unit> | ||
74 | <trans-unit id="Unmute"> | ||
75 | <source>Unmute</source> | ||
76 | <target>Son activé</target> | ||
77 | </trans-unit> | ||
78 | <trans-unit id="Playback Rate"> | ||
79 | <source>Playback Rate</source> | ||
80 | <target>Vitesse de lecture</target> | ||
81 | </trans-unit> | ||
82 | <trans-unit id="Subtitles"> | ||
83 | <source>Subtitles</source> | ||
84 | <target>Sous-titres</target> | ||
85 | </trans-unit> | ||
86 | <trans-unit id="subtitles off"> | ||
87 | <source>subtitles off</source> | ||
88 | <target>Sous-titres désactivés</target> | ||
89 | </trans-unit> | ||
90 | <trans-unit id="Captions"> | ||
91 | <source>Captions</source> | ||
92 | <target>Sous-titres transcrits</target> | ||
93 | </trans-unit> | ||
94 | <trans-unit id="captions off"> | ||
95 | <source>captions off</source> | ||
96 | <target>Sous-titres transcrits désactivés</target> | ||
97 | </trans-unit> | ||
98 | <trans-unit id="Chapters"> | ||
99 | <source>Chapters</source> | ||
100 | <target>Chapitres</target> | ||
101 | </trans-unit> | ||
102 | <trans-unit id="Descriptions"> | ||
103 | <source>Descriptions</source> | ||
104 | <target>Descriptions</target> | ||
105 | </trans-unit> | ||
106 | <trans-unit id="descriptions off"> | ||
107 | <source>descriptions off</source> | ||
108 | <target>descriptions désactivées</target> | ||
109 | </trans-unit> | ||
110 | <trans-unit id="Audio Track"> | ||
111 | <source>Audio Track</source> | ||
112 | <target>Piste audio</target> | ||
113 | </trans-unit> | ||
114 | <trans-unit id="Volume Level"> | ||
115 | <source>Volume Level</source> | ||
116 | <target>Niveau de volume</target> | ||
117 | </trans-unit> | ||
118 | <trans-unit id="You aborted the media playback"> | ||
119 | <source>You aborted the media playback</source> | ||
120 | <target>Vous avez interrompu la lecture de la vidéo.</target> | ||
121 | </trans-unit> | ||
122 | <trans-unit id="A network error caused the media download to fail part-way."> | ||
123 | <source>A network error caused the media download to fail part-way.</source> | ||
124 | <target>Une erreur de réseau a interrompu le téléchargement de la vidéo.</target> | ||
125 | </trans-unit> | ||
126 | <trans-unit id="The media could not be loaded, either because the server or network failed or because the format is not supported."> | ||
127 | <source>The media could not be loaded, either because the server or network failed or because the format is not supported.</source> | ||
128 | <target>Cette vidéo n'a pas pu être chargée, soit parce que le serveur ou le réseau a échoué ou parce que le format n'est pas reconnu.</target> | ||
129 | </trans-unit> | ||
130 | <trans-unit id="The media playback was aborted due to a corruption problem or because the media used features your browser did not support."> | ||
131 | <source>The media playback was aborted due to a corruption problem or because the media used features your browser did not support.</source> | ||
132 | <target>La lecture de la vidéo a été interrompue à cause d'un problème de corruption ou parce que la vidéo utilise des fonctionnalités non prises en charge par votre navigateur.</target> | ||
133 | </trans-unit> | ||
134 | <trans-unit id="No compatible source was found for this media."> | ||
135 | <source>No compatible source was found for this media.</source> | ||
136 | <target>Aucune source compatible n'a été trouvée pour cette vidéo.</target> | ||
137 | </trans-unit> | ||
138 | <trans-unit id="The media is encrypted and we do not have the keys to decrypt it."> | ||
139 | <source>The media is encrypted and we do not have the keys to decrypt it.</source> | ||
140 | <target>Le média est chiffré et nous n'avons pas les clés pour le déchiffrer.</target> | ||
141 | </trans-unit> | ||
142 | <trans-unit id="Play Video"> | ||
143 | <source>Play Video</source> | ||
144 | <target>Lire la vidéo</target> | ||
145 | </trans-unit> | ||
146 | <trans-unit id="Close"> | ||
147 | <source>Close</source> | ||
148 | <target>Fermer</target> | ||
149 | </trans-unit> | ||
150 | <trans-unit id="Close Modal Dialog"> | ||
151 | <source>Close Modal Dialog</source> | ||
152 | <target>Fermer la boîte de dialogue modale</target> | ||
153 | </trans-unit> | ||
154 | <trans-unit id="Modal Window"> | ||
155 | <source>Modal Window</source> | ||
156 | <target>Fenêtre modale</target> | ||
157 | </trans-unit> | ||
158 | <trans-unit id="This is a modal window"> | ||
159 | <source>This is a modal window</source> | ||
160 | <target>Ceci est une fenêtre modale</target> | ||
161 | </trans-unit> | ||
162 | <trans-unit id="This modal can be closed by pressing the Escape key or activating the close button."> | ||
163 | <source>This modal can be closed by pressing the Escape key or activating the close button.</source> | ||
164 | <target>Ce modal peut être fermé en appuyant sur la touche Échap ou activer le bouton de fermeture.</target> | ||
165 | </trans-unit> | ||
166 | <trans-unit id=", opens captions settings dialog"> | ||
167 | <source>, opens captions settings dialog</source> | ||
168 | <target>, ouvrir les paramètres des sous-titres transcrits</target> | ||
169 | </trans-unit> | ||
170 | <trans-unit id=", opens subtitles settings dialog"> | ||
171 | <source>, opens subtitles settings dialog</source> | ||
172 | <target>, ouvrir les paramètres des sous-titres</target> | ||
173 | </trans-unit> | ||
174 | <trans-unit id=", opens descriptions settings dialog"> | ||
175 | <source>, opens descriptions settings dialog</source> | ||
176 | <target>, ouvrir les paramètres des descriptions</target> | ||
177 | </trans-unit> | ||
178 | <trans-unit id=", selected"> | ||
179 | <source>, selected</source> | ||
180 | <target>, sélectionné</target> | ||
181 | </trans-unit> | ||
182 | <trans-unit id="captions settings"> | ||
183 | <source>captions settings</source> | ||
184 | <target>Paramètres des sous-titres transcrits</target> | ||
185 | </trans-unit> | ||
186 | <trans-unit id="subtitles settings"> | ||
187 | <source>subititles settings</source> | ||
188 | <target>Paramètres des sous-titres</target> | ||
189 | </trans-unit> | ||
190 | <trans-unit id="descriptions settings"> | ||
191 | <source>descriptions settings</source> | ||
192 | <target>Paramètres des descriptions</target> | ||
193 | </trans-unit> | ||
194 | <trans-unit id="Text"> | ||
195 | <source>Text</source> | ||
196 | <target>Texte</target> | ||
197 | </trans-unit> | ||
198 | <trans-unit id="White"> | ||
199 | <source>White</source> | ||
200 | <target>Blanc</target> | ||
201 | </trans-unit> | ||
202 | <trans-unit id="Black"> | ||
203 | <source>Black</source> | ||
204 | <target>Noir</target> | ||
205 | </trans-unit> | ||
206 | <trans-unit id="Red"> | ||
207 | <source>Red</source> | ||
208 | <target>Rouge</target> | ||
209 | </trans-unit> | ||
210 | <trans-unit id="Green"> | ||
211 | <source>Green</source> | ||
212 | <target>Vert</target> | ||
213 | </trans-unit> | ||
214 | <trans-unit id="Blue"> | ||
215 | <source>Blue</source> | ||
216 | <target>Bleu</target> | ||
217 | </trans-unit> | ||
218 | <trans-unit id="Yellow"> | ||
219 | <source>Yellow</source> | ||
220 | <target>Jaune</target> | ||
221 | </trans-unit> | ||
222 | <trans-unit id="Magenta"> | ||
223 | <source>Magenta</source> | ||
224 | <target>Magenta</target> | ||
225 | </trans-unit> | ||
226 | <trans-unit id="Cyan"> | ||
227 | <source>Cyan</source> | ||
228 | <target>Cyan</target> | ||
229 | </trans-unit> | ||
230 | <trans-unit id="Background"> | ||
231 | <source>Background</source> | ||
232 | <target>Arrière-plan</target> | ||
233 | </trans-unit> | ||
234 | <trans-unit id="Window"> | ||
235 | <source>Window</source> | ||
236 | <target>Fenêtre</target> | ||
237 | </trans-unit> | ||
238 | <trans-unit id="Transparent"> | ||
239 | <source>Transparent</source> | ||
240 | <target>Transparent</target> | ||
241 | </trans-unit> | ||
242 | <trans-unit id="Semi-Transparent"> | ||
243 | <source>Semi-Transparent</source> | ||
244 | <target>Semi-transparent</target> | ||
245 | </trans-unit> | ||
246 | <trans-unit id="Opaque"> | ||
247 | <source>Opaque</source> | ||
248 | <target>Opaque</target> | ||
249 | </trans-unit> | ||
250 | <trans-unit id="Font Size"> | ||
251 | <source>Font Size</source> | ||
252 | <target>Taille des caractères</target> | ||
253 | </trans-unit> | ||
254 | <trans-unit id="Text Edge Style"> | ||
255 | <source>Text Edge Style</source> | ||
256 | <target>Style des contours du texte</target> | ||
257 | </trans-unit> | ||
258 | <trans-unit id="None"> | ||
259 | <source>None</source> | ||
260 | <target>Aucun</target> | ||
261 | </trans-unit> | ||
262 | <trans-unit id="Raised"> | ||
263 | <source>Raised</source> | ||
264 | <target>Élevé</target> | ||
265 | </trans-unit> | ||
266 | <trans-unit id="Depressed"> | ||
267 | <source>Depressed</source> | ||
268 | <target>Enfoncé</target> | ||
269 | </trans-unit> | ||
270 | <trans-unit id="Uniform"> | ||
271 | <source>Uniform</source> | ||
272 | <target>Uniforme</target> | ||
273 | </trans-unit> | ||
274 | <trans-unit id="Dropshadow"> | ||
275 | <source>Dropshadow</source> | ||
276 | <target>Ombre portée</target> | ||
277 | </trans-unit> | ||
278 | <trans-unit id="Font Family"> | ||
279 | <source>Font Family</source> | ||
280 | <target>Familles de polices</target> | ||
281 | </trans-unit> | ||
282 | <trans-unit id="Proportional Sans-Serif"> | ||
283 | <source>Proportional Sans-Serif</source> | ||
284 | <target>Polices à chasse variable sans empattement (Proportional Sans-Serif)</target> | ||
285 | </trans-unit> | ||
286 | <trans-unit id="Monospace Sans-Serif"> | ||
287 | <source>Monospace Sans-Serif</source> | ||
288 | <target>Polices à chasse fixe sans empattement (Monospace Sans-Serif)</target> | ||
289 | </trans-unit> | ||
290 | <trans-unit id="Proportional Serif"> | ||
291 | <source>Proportional Serif</source> | ||
292 | <target>Polices à chasse variable avec empattement (Proportional Serif)</target> | ||
293 | </trans-unit> | ||
294 | <trans-unit id="Monospace Serif"> | ||
295 | <source>Monospace Serif</source> | ||
296 | <target>Polices à chasse fixe avec empattement (Monospace Serif)</target> | ||
297 | </trans-unit> | ||
298 | <trans-unit id="Casual"> | ||
299 | <source>Casual</source> | ||
300 | <target>Manuscrite</target> | ||
301 | </trans-unit> | ||
302 | <trans-unit id="Script"> | ||
303 | <source>Script</source> | ||
304 | <target>Scripte</target> | ||
305 | </trans-unit> | ||
306 | <trans-unit id="Small Caps"> | ||
307 | <source>Small Caps</source> | ||
308 | <target>Petites capitales</target> | ||
309 | </trans-unit> | ||
310 | <trans-unit id="Reset"> | ||
311 | <source>Reset</source> | ||
312 | <target>Réinitialiser</target> | ||
313 | </trans-unit> | ||
314 | <trans-unit id="restore all settings to the default values"> | ||
315 | <source>restore all settings to the default values</source> | ||
316 | <target>Restaurer tous les paramètres aux valeurs par défaut</target> | ||
317 | </trans-unit> | ||
318 | <trans-unit id="Done"> | ||
319 | <source>Done</source> | ||
320 | <target>Terminé</target> | ||
321 | </trans-unit> | ||
322 | <trans-unit id="Caption Settings Dialog"> | ||
323 | <source>Caption Settings Dialog</source> | ||
324 | <target>Boîte de dialogue des paramètres des sous-titres transcrits</target> | ||
325 | </trans-unit> | ||
326 | <trans-unit id="Beginning of dialog window. Escape will cancel and close the window."> | ||
327 | <source>Beginning of dialog window. Escape will cancel and close the window.</source> | ||
328 | <target>Début de la fenêtre de dialogue. La touche d'échappement annulera et fermera la fenêtre.</target> | ||
329 | </trans-unit> | ||
330 | <trans-unit id="End of dialog window."> | ||
331 | <source>End of dialog window.</source> | ||
332 | <target>Fin de la fenêtre de dialogue.</target> | ||
333 | </trans-unit> | ||
334 | <trans-unit id="{1} is loading."> | ||
335 | <source>{1} is loading.</source> | ||
336 | <target>{1} est en train de charger</target> | ||
337 | </trans-unit> | ||
338 | <trans-unit id="Quality"> | ||
339 | <source>Quality</source> | ||
340 | <target>Qualité</target> | ||
341 | </trans-unit> | ||
342 | <trans-unit id="Auto"> | ||
343 | <source>Auto</source> | ||
344 | <target>Auto</target> | ||
345 | </trans-unit> | ||
346 | <trans-unit id="Speed"> | ||
347 | <source>Speed</source> | ||
348 | <target>Vitesse</target> | ||
349 | </trans-unit> | ||
350 | <trans-unit id="peers"> | ||
351 | <source>peers</source> | ||
352 | <target>pairs</target> | ||
353 | </trans-unit> | ||
354 | <trans-unit id="Go to the video page"> | ||
355 | <source>Go to the video page</source> | ||
356 | <target>Aller sur la page de la vidéo</target> | ||
357 | </trans-unit> | ||
358 | <trans-unit id="Settings"> | ||
359 | <source>Settings</source> | ||
360 | <target>Paramètres</target> | ||
361 | </trans-unit> | ||
362 | <trans-unit id="Uses P2P, others may know you are watching this video."> | ||
363 | <source>Uses P2P, others may know you are watching this video.</source> | ||
364 | <target>Utilise le P2P, d'autres personnes pourraient savoir que vous regardez cette vidéo.</target> | ||
365 | </trans-unit> | ||
366 | <trans-unit id="Copy the video URL"> | ||
367 | <source>Copy the video URL</source> | ||
368 | <target>Copier le lien de la vidéo</target> | ||
369 | </trans-unit> | ||
370 | <trans-unit id="Copy the video URL at the current time"> | ||
371 | <source>Copy the video URL at the current time</source> | ||
372 | <target>Copier le lien de la vidéo à partir de cette séquence</target> | ||
373 | </trans-unit> | ||
374 | <trans-unit id="Copy embed code"> | ||
375 | <source>Copy embed code</source> | ||
376 | <target>Copier le code d'intégration</target> | ||
377 | </trans-unit> | ||
378 | </body> | ||
379 | </file></xliff> \ No newline at end of file | ||
diff --git a/client/src/locale/target/server_fr.json b/client/src/locale/target/server_fr.json new file mode 100644 index 000000000..43216adf4 --- /dev/null +++ b/client/src/locale/target/server_fr.json | |||
@@ -0,0 +1 @@ | |||
{"Music":"Musique","Films":"Films","Vehicles":"Transport","Art":"Art","Sports":"Sports","Travels":"Voyages","Gaming":"Jeux vidéos","People":"People","Comedy":"Humour","Entertainment":"Divertissement","News":"Actualités","How To":"Tutoriel","Education":"Éducation","Activism":"Activisme","Science & Technology":"Science & Technologie","Animals":"Animaux","Kids":"Enfants","Food":"Cuisine","Attribution":"Attribution","Attribution - Share Alike":"Attribution - Partage dans les mêmes conditions","Attribution - No Derivatives":"Attribution - Pas d'oeuvre dérivée","Attribution - Non Commercial":"Attribution - Utilisation non commerciale","Attribution - Non Commercial - Share Alike":"Attribution - Utilisation non commerciale - Partage dans les mêmes conditions","Attribution - Non Commercial - No Derivatives":"Attribution - Utilisation non commerciale - Pas d'oeuvre dérivée","Public Domain Dedication":"Domaine public","Public":"Publique","Unlisted":"Non listée","Private":"Privée","French":"Français","French Sign Language":"Langage des signes français","Misc":"Divers","Unknown":"Inconnu"} \ No newline at end of file | |||
diff --git a/scripts/i18n/create-custom-files.ts b/scripts/i18n/create-custom-files.ts index d8a87f291..3519afd47 100755 --- a/scripts/i18n/create-custom-files.ts +++ b/scripts/i18n/create-custom-files.ts | |||
@@ -1,12 +1,15 @@ | |||
1 | import * as jsToXliff12 from 'xliff/jsToXliff12' | 1 | import * as jsToXliff12 from 'xliff/jsToXliff12' |
2 | import { writeFile } from 'fs' | 2 | import { writeFile } from 'fs' |
3 | import { join } from 'path' | 3 | import { join } from 'path' |
4 | import { buildLanguages, VIDEO_CATEGORIES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../server/initializers/constants' | ||
5 | import { values } from 'lodash' | ||
4 | 6 | ||
5 | // First, the player | 7 | type TranslationType = { |
6 | const playerSource = join(__dirname, '../../../client/src/locale/source/videojs_en_US.json') | 8 | target: string |
7 | const playerTarget = join(__dirname, '../../../client/src/locale/source/player_en_US.xml') | 9 | data: { [id: string]: string } |
10 | } | ||
8 | 11 | ||
9 | const videojs = require(playerSource) | 12 | const videojs = require(join(__dirname, '../../../client/src/locale/source/videojs_en_US.json')) |
10 | const playerKeys = { | 13 | const playerKeys = { |
11 | 'Quality': 'Quality', | 14 | 'Quality': 'Quality', |
12 | 'Auto': 'Auto', | 15 | 'Auto': 'Auto', |
@@ -19,36 +22,65 @@ const playerKeys = { | |||
19 | 'Copy the video URL at the current time': 'Copy the video URL at the current time', | 22 | 'Copy the video URL at the current time': 'Copy the video URL at the current time', |
20 | 'Copy embed code': 'Copy embed code' | 23 | 'Copy embed code': 'Copy embed code' |
21 | } | 24 | } |
22 | 25 | const playerTranslations = { | |
23 | const obj = { | 26 | target: join(__dirname, '../../../client/src/locale/source/player_en_US.xml'), |
24 | resources: { | 27 | data: Object.assign({}, videojs, playerKeys) |
25 | namespace1: {} | ||
26 | } | ||
27 | } | 28 | } |
28 | 29 | ||
29 | for (const sourceObject of [ videojs, playerKeys ]) { | 30 | // Server keys |
30 | Object.keys(sourceObject).forEach(k => obj.resources.namespace1[ k ] = { source: sourceObject[ k ] }) | 31 | const serverKeys: any = {} |
32 | values(VIDEO_CATEGORIES) | ||
33 | .concat(values(VIDEO_LICENCES)) | ||
34 | .concat(values(VIDEO_PRIVACIES)) | ||
35 | .forEach(v => serverKeys[v] = v) | ||
36 | |||
37 | // ISO 639 keys | ||
38 | const languages = buildLanguages() | ||
39 | Object.keys(languages).forEach(k => serverKeys[languages[k]] = languages[k]) | ||
40 | |||
41 | // More keys | ||
42 | Object.assign(serverKeys, { | ||
43 | 'Misc': 'Misc', | ||
44 | 'Unknown': 'Unknown' | ||
45 | }) | ||
46 | |||
47 | const serverTranslations = { | ||
48 | target: join(__dirname, '../../../client/src/locale/source/server_en_US.xml'), | ||
49 | data: serverKeys | ||
31 | } | 50 | } |
32 | 51 | ||
33 | saveToXliffFile(playerTarget, obj, err => { | 52 | saveToXliffFile(playerTranslations, err => { |
34 | if (err) { | 53 | if (err) return handleError(err) |
35 | console.error(err) | 54 | |
36 | process.exit(-1) | 55 | saveToXliffFile(serverTranslations, err => { |
37 | } | 56 | if (err) return handleError(err) |
38 | 57 | ||
39 | process.exit(0) | 58 | process.exit(0) |
59 | }) | ||
40 | }) | 60 | }) |
41 | 61 | ||
42 | // Then, the server strings | 62 | // Then, the server strings |
43 | 63 | ||
44 | function saveToXliffFile (targetPath: string, obj: any, cb: Function) { | 64 | function saveToXliffFile (jsonTranslations: TranslationType, cb: Function) { |
65 | const obj = { | ||
66 | resources: { | ||
67 | namespace1: {} | ||
68 | } | ||
69 | } | ||
70 | Object.keys(jsonTranslations.data).forEach(k => obj.resources.namespace1[ k ] = { source: jsonTranslations.data[ k ] }) | ||
71 | |||
45 | jsToXliff12(obj, (err, res) => { | 72 | jsToXliff12(obj, (err, res) => { |
46 | if (err) return cb(err) | 73 | if (err) return cb(err) |
47 | 74 | ||
48 | writeFile(playerTarget, res, err => { | 75 | writeFile(jsonTranslations.target, res, err => { |
49 | if (err) return cb(err) | 76 | if (err) return cb(err) |
50 | 77 | ||
51 | return cb(null) | 78 | return cb(null) |
52 | }) | 79 | }) |
53 | }) | 80 | }) |
54 | } | 81 | } |
82 | |||
83 | function handleError (err: any) { | ||
84 | console.error(err) | ||
85 | process.exit(-1) | ||
86 | } \ No newline at end of file | ||
diff --git a/scripts/i18n/xliff2json.ts b/scripts/i18n/xliff2json.ts index 34784ac11..fa5a71d65 100755 --- a/scripts/i18n/xliff2json.ts +++ b/scripts/i18n/xliff2json.ts | |||
@@ -1,33 +1,53 @@ | |||
1 | import * as xliff12ToJs from 'xliff/xliff12ToJs' | 1 | import * as xliff12ToJs from 'xliff/xliff12ToJs' |
2 | import { readFileSync, writeFile } from 'fs' | 2 | import { unlink, readFileSync, writeFile } from 'fs' |
3 | import { join } from 'path' | 3 | import { join } from 'path' |
4 | import { buildFileLocale, I18N_LOCALES, isDefaultLocale } from '../../shared/models/i18n/i18n' | ||
5 | import { eachSeries } from 'async' | ||
4 | 6 | ||
5 | // First, the player | 7 | const sources: string[] = [] |
6 | const playerSource = join(__dirname, '../../../client/src/locale/target/player_fr.xml') | 8 | const availableLocales = Object.keys(I18N_LOCALES) |
7 | const playerTarget = join(__dirname, '../../../client/src/locale/target/player_fr.json') | 9 | .filter(l => isDefaultLocale(l) === false) |
10 | .map(l => buildFileLocale(l)) | ||
8 | 11 | ||
9 | // Remove the two first lines our xliff module does not like | 12 | for (const file of [ 'server', 'player' ]) { |
10 | let playerFile = readFileSync(playerSource).toString() | 13 | for (const locale of availableLocales) { |
11 | playerFile = removeFirstLine(playerFile) | 14 | sources.push(join(__dirname, '../../../client/src/locale/target/', `${file}_${locale}.xml`)) |
12 | playerFile = removeFirstLine(playerFile) | ||
13 | |||
14 | xliff12ToJs(playerFile, (err, res) => { | ||
15 | if (err) { | ||
16 | console.error(err) | ||
17 | process.exit(-1) | ||
18 | } | 15 | } |
16 | } | ||
19 | 17 | ||
20 | const json = createJSONString(res) | 18 | eachSeries(sources, (source, cb) => { |
21 | writeFile(playerTarget, json, err => { | 19 | xliffFile2JSON(source, cb) |
22 | if (err) { | 20 | }, err => { |
23 | console.error(err) | 21 | if (err) return handleError(err) |
24 | process.exit(-1) | ||
25 | } | ||
26 | 22 | ||
27 | process.exit(0) | 23 | process.exit(0) |
28 | }) | ||
29 | }) | 24 | }) |
30 | 25 | ||
26 | function handleError (err: any) { | ||
27 | console.error(err) | ||
28 | process.exit(-1) | ||
29 | } | ||
30 | |||
31 | function xliffFile2JSON (filePath: string, cb) { | ||
32 | const fileTarget = filePath.replace('.xml', '.json') | ||
33 | |||
34 | // Remove the two first lines our xliff module does not like | ||
35 | let fileContent = readFileSync(filePath).toString() | ||
36 | fileContent = removeFirstLine(fileContent) | ||
37 | fileContent = removeFirstLine(fileContent) | ||
38 | |||
39 | xliff12ToJs(fileContent, (err, res) => { | ||
40 | if (err) return cb(err) | ||
41 | |||
42 | const json = createJSONString(res) | ||
43 | writeFile(fileTarget, json, err => { | ||
44 | if (err) return cb(err) | ||
45 | |||
46 | return unlink(filePath, cb) | ||
47 | }) | ||
48 | }) | ||
49 | } | ||
50 | |||
31 | function removeFirstLine (str: string) { | 51 | function removeFirstLine (str: string) { |
32 | return str.substring(str.indexOf('\n') + 1) | 52 | return str.substring(str.indexOf('\n') + 1) |
33 | } | 53 | } |
diff --git a/server/controllers/client.ts b/server/controllers/client.ts index b153f6086..ec78a4bbc 100644 --- a/server/controllers/client.ts +++ b/server/controllers/client.ts | |||
@@ -48,8 +48,11 @@ clientsRouter.use('/client', express.static(distPath, { maxAge: STATIC_MAX_AGE } | |||
48 | clientsRouter.use('/client/assets/images', express.static(assetsImagesPath, { maxAge: STATIC_MAX_AGE })) | 48 | clientsRouter.use('/client/assets/images', express.static(assetsImagesPath, { maxAge: STATIC_MAX_AGE })) |
49 | 49 | ||
50 | clientsRouter.use('/client/locales/:locale/:file.json', function (req, res) { | 50 | clientsRouter.use('/client/locales/:locale/:file.json', function (req, res) { |
51 | if (req.params.locale === 'fr' && req.params.file === 'player') { | 51 | const locale = req.params.locale |
52 | return res.sendFile(join(__dirname, '../../../client/dist/locale/player_fr.json')) | 52 | const file = req.params.file |
53 | |||
54 | if (is18nLocale(locale) && [ 'player', 'server' ].indexOf(file) !== -1) { | ||
55 | return res.sendFile(join(__dirname, `../../../client/dist/locale/${file}_${locale}.json`)) | ||
53 | } | 56 | } |
54 | 57 | ||
55 | return res.sendStatus(404) | 58 | return res.sendStatus(404) |
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 26ee3db47..9b459c241 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -500,7 +500,8 @@ export { | |||
500 | STATIC_DOWNLOAD_PATHS, | 500 | STATIC_DOWNLOAD_PATHS, |
501 | RATES_LIMIT, | 501 | RATES_LIMIT, |
502 | JOB_COMPLETED_LIFETIME, | 502 | JOB_COMPLETED_LIFETIME, |
503 | VIDEO_VIEW_LIFETIME | 503 | VIDEO_VIEW_LIFETIME, |
504 | buildLanguages | ||
504 | } | 505 | } |
505 | 506 | ||
506 | // --------------------------------------------------------------------------- | 507 | // --------------------------------------------------------------------------- |