diff --git a/client/package.json b/client/package.json
index 6c1d15275..42c43c5c5 100644
--- a/client/package.json
+++ b/client/package.json
@@ -9,7 +9,8 @@
"lint": "ng lint",
"e2e": "ng e2e",
"compodoc": "./node_modules/.bin/compodoc --hideGenerator -p src/tsconfig.app.json -n 'OpenSlides Documentation' -d ../Compodoc -s -w -t -o --port",
- "extract": "ngx-translate-extract -i ./src -o ./src/assets/i18n/{en,de,fr}.json --clean --sort --format-indentation ' ' --format namespaced-json",
+ "extract": "ngx-translate-extract -i ./src -o ./src/assets/i18n/template-en.pot -clean --sort --format pot -m _",
+ "po2json": "./node_modules/.bin/po2json -f mf src/assets/i18n/de.po src/assets/i18n/de.json && ./node_modules/.bin/po2json -f mf src/assets/i18n/cs.po src/assets/i18n/cs.json",
"prettify": "pretty-quick"
},
"private": true,
@@ -32,6 +33,7 @@
"file-saver": "^2.0.0-rc.3",
"material-design-icons": "^3.0.1",
"ngx-mat-select-search": "^1.4.0",
+ "po2json": "^1.0.0-alpha",
"roboto-fontface": "^0.10.0",
"rxjs": "^6.3.3",
"uuid": "^3.3.2",
@@ -47,6 +49,7 @@
"@types/jasmine": "^2.8.9",
"@types/jasminewd2": "^2.0.5",
"@types/node": "~8.9.4",
+ "@types/yargs": "^12.0.1",
"codelyzer": "~4.2.1",
"husky": "^0.14.3",
"jasmine-core": "~2.99.1",
diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts
index b5e48b7f6..38e0c0d8c 100644
--- a/client/src/app/app.component.ts
+++ b/client/src/app/app.component.ts
@@ -33,7 +33,7 @@ export class AppComponent {
constantsService: ConstantsService // Needs to be started, so it can register itself to the WebsocketService
) {
// manually add the supported languages
- translate.addLangs(['en', 'de', 'fr']);
+ translate.addLangs(['en', 'de', 'cs']);
// this language will be used as a fallback when a translation isn't found in the current language
translate.setDefaultLang('en');
// get the browsers default language
diff --git a/client/src/app/core/marked-translations.ts b/client/src/app/core/marked-translations.ts
new file mode 100644
index 000000000..916641694
--- /dev/null
+++ b/client/src/app/core/marked-translations.ts
@@ -0,0 +1,305 @@
+import { _ } from '@biesbjerg/ngx-translate-extract';
+
+/**
+ * Add strings here that require translations but have never been declared
+ * in code nor views.
+ *
+ * I.e: words transmitted by the server
+ *
+ * @example
+ * ```ts
+ * _('my new sentence to translate that has not been anywhere');
+ * ```
+ */
+
+// Core config strings
+_('Presentation and assembly system');
+_('Event name');
+_('OpenSlides is a free ' +
+ 'web based presentation and assembly system for visualizing ' +
+ 'and controlling agenda, motions and elections of an ' +
+ 'assembly.');
+_('General');
+_('Event');
+_('Short description of event');
+_('Event date');
+_('Event location');
+_('Event organizer');
+_('Front page title');
+_('Welcome to OpenSlides');
+_('Front page text');
+_('[Space for your welcome text.]');
+_('System');
+_('Allow access for anonymous guest users');
+_('Show this text on the login page');
+_('Export');
+_('Separator used for all csv exports and examples');
+_('Page number alignment in PDF');
+_('Left');
+_('Center');
+_('Right');
+_('Standard font size in PDF');
+
+// Projector config strings
+_('Projector');
+_('Projector language');
+_('Current browser language');
+_('Show logo on projector');
+_('You can replace the logo by uploading an image and set it as the "Projector logo" in "files".');
+_('Show the clock on projector');
+_('Show title and description of event on projector');
+_('Display header and footer');
+_('Background color of projector header and footer');
+_('Font color of projector header and footer');
+_('Font color of projector headline');
+_('Predefined seconds of new countdowns');
+_('Color for blanked projector');
+_('Default projector');
+_('Custom translations');
+_('List of speakers overlay');
+_('Projector logo');
+_('Projector header image');
+_('PDF header logo (left)');
+_('PDF header logo (right)');
+_('PDF footer logo (left)');
+_('PDF footer logo (right)');
+_('Web interface header logo');
+_('PDF ballot paper logo');
+
+// Agenda config strings
+_('Enable numbering for agenda items');
+_('Numbering prefix for agenda items');
+_('This prefix will be set if you run the automatic agenda numbering.');
+_('Agenda');
+_('Invalid input.');
+_('Numeral system for agenda items');
+_('Arabic');
+_('Roman');
+_('Begin of event');
+_('Input format: DD.MM.YYYY HH:MM');
+_('Hide internal items when projecting subitems');
+_('Number of last speakers to be shown on the projector');
+_('List of speakers');
+_('Show orange countdown in the last x seconds of speaking time');
+_('Enter duration in seconds. Choose 0 to disable warning color.');
+_('Couple countdown with the list of speakers');
+_('[Begin speech] starts the countdown, [End speech] stops the countdown.');
+_('Agenda visibility');
+_('Default visibility for new agenda items (except topics)');
+_('Public item');
+_('Internal item');
+_('Hidden item');
+
+
+// Motions config strings
+// subgroup general
+_('General');
+_('Workflow of new motions');
+_('Numbered per category');
+_('Serially numbered');
+_('Set it manually');
+_('Motion preamble');
+_('The assembly may decide:');
+_('Default line numbering');
+_('disabled');
+_('Line length');
+_('The maximum number of characters per line. Relevant when line numbering is enabled. Min: 40');
+_('Hide reason on projector');
+_('Hide meta information box on projector');
+_('Hide recommendation on projector');
+_('Stop submitting new motions by non-staff users');
+_('Allow to disable versioning');
+_('Name of recommender');
+_('Will be displayed as label before selected recommendation. Use an empty value to disable the recommendation system.');
+_('Default text version for change recommendations');
+// subgroup Amendments
+_('Amendments');
+_('Activate amendments');
+_('Show amendments together with motions');
+_('Prefix for the identifier for amendments');
+_('The title of the motion is always applied.');
+_('How to create new amendments');
+_('Empty text field');
+_('Edit the whole motion text');
+_('Paragraph-based, Diff-enabled');
+// subgroup Supporters
+_('Supporters');
+_('Number of (minimum) required supporters for a motion');
+_('Choose 0 to disable the supporting system.');
+_('Remove all supporters of a motion if a submitter edits his motion in early state');
+// subgroup Voting and ballot papers
+_('Voting and ballot papers');
+_('The 100 % base of a voting result consists of');
+_('Yes/No/Abstain');
+_('Yes/No');
+_('All valid ballots');
+_('All casted ballots');
+_('Disabled (no percents)');
+_('Required majority');
+_('Default method to check whether a motion has reached the required majority.');
+_('Simple majority');
+_('Two-thirds majority');
+_('Three-quarters majority');
+_('Disabled');
+_('Number of ballot papers (selection)');
+_('Number of all delegates');
+_('Number of all participants');
+_('Use the following custom number');
+_('Custom number of ballot papers');
+// subgroup export
+_('Title for PDF and DOCX documents (all motions)');
+_('Preamble text for PDF and DOCX documents (all motions)');
+_('Sort categories by');
+_('Include the sequential number in PDF and DOCX');
+// misc motion strings
+_('needed');
+_('Amendment');
+_('Amendment to');
+// motion workflow 1
+_('Simple Workflow');
+_('submitted');
+_('accepted');
+_('Accept');
+_('Acceptance');
+_('rejected');
+_('Reject');
+_('Rejection');
+_('not decided');
+_('Do not decide');
+_('No decision');
+// motion workflow 2
+_('Complex Workflow');
+_('published');
+_('permitted');
+_('Permit');
+_('Permission');
+_('accepted');
+_('Accept');
+_('Acceptance');
+_('rejected');
+_('Reject');
+_('Rejection');
+_('withdrawed');
+_('Withdraw');
+_('adjourned');
+_('Adjourn');
+_('Adjournment');
+_('not concerned');
+_('Do not concern');
+_('No concernment');
+_('refered to committee');
+_('Refer to committee');
+_('Referral to committee');
+_('needs review');
+_('Needs review');
+_('rejected (not authorized)');
+_('Reject (not authorized)');
+_('Rejection (not authorized)');
+
+// Assignment config strings
+_('Election method');
+_('Automatic assign of method');
+_('Always one option per candidate');
+_('Always Yes-No-Abstain per candidate');
+_('Always Yes/No per candidate');
+_('Elections');
+_('Ballot and ballot papers');
+_('The 100-%-base of an election result consists of');
+_('For Yes/No/Abstain per candidate and Yes/No per candidate the 100-%-base ' +
+ 'depends on the election method: If there is only one option per candidate, ' +
+ 'the sum of all votes of all candidates is 100 %. Otherwise for each ' +
+ 'candidate the sum of all votes is 100 %.');
+_('Yes/No/Abstain per candidate');
+_('Yes/No per candidate');
+_('All valid ballots');
+_('All casted ballots');
+_('Disabled (no percents)');
+_('Number of ballot papers (selection)');
+_('Number of all delegates');
+_('Number of all participants');
+_('Use the following custom number');
+_('Custom number of ballot papers');
+_('Required majority');
+_('Default method to check whether a candidate has reached the required majority.');
+_('Simple majority');
+_('Two-thirds majority');
+_('Three-quarters majority');
+_('Disabled');
+_('Put all candidates on the list of speakers');
+_('Title for PDF document (all elections)');
+_('Preamble text for PDF document (all elections)');
+//other translations
+_('Searching for candidates');
+_('Voting');
+_('Finished');
+
+// Users
+// permission strings (see models.py of each Django app)
+// agenda
+_('Can see agenda');
+_('Can manage agenda');
+_('Can manage list of speakers');
+_('Can see internal items and time scheduling of agenda');
+_('Can put oneself on the list of speakers');
+// assignments
+_('Can see elections');
+_('Can nominate another participant');
+_('Can nominate oneself');
+_('Can manage elections');
+// core
+_('Can see the projector');
+_('Can manage the projector');
+_('Can see the front page');
+_('Can manage tags');
+_('Can manage configuration');
+_('Can use the chat');
+_('Can manage the chat');
+_('Can manage logos and fonts');
+// mediafiles
+_('Can see the list of files');
+_('Can upload files');
+_('Can manage files');
+_('Can see hidden files');
+// motions
+_('Can see motions');
+_('Can create motions');
+_('Can support motions');
+_('Can manage motions');
+_('Can see comments');
+_('Can manage comments');
+// users
+_('Can see names of users');
+_('Can see extra data of users (e.g. present and comment)');
+_('Can manage users');
+
+// users config strings
+_('General');
+_('Sort name of participants by');
+_('Enable participant presence view');
+_('Participants');
+_('Given name');
+_('Surname');
+_('PDF');
+_('Welcome to OpenSlides');
+_('Title for access data and welcome PDF');
+_('[Place for your welcome and help text.]');
+_('Help text for access data and welcome PDF');
+_('System URL');
+_('Used for QRCode in PDF of access data.');
+_('WLAN name (SSID)');
+_('Used for WLAN QRCode in PDF of access data.');
+_('WLAN password');
+_('Used for WLAN QRCode in PDF of access data.');
+_('WLAN encryption');
+_('Used for WLAN QRCode in PDF of access data.');
+_('WEP');
+_('WPA/WPA2');
+_('No encryption');
+_('Email');
+_('Email sender');
+_('Email subject');
+_('Your login for {event_name}');
+_('You can use {event_name} as a placeholder.');
+_('Email body');
+_('Dear {name},\n\nthis is your OpenSlides login for the event {event_name}:\n\n {url}\n username: {username}\n password: {password}\n\nThis email was generated automatically.');
+_('Use these placeholders: {name}, {event_name}, {url}, {username}, {password}. The url referrs to the system url.');
diff --git a/client/src/app/shared/components/footer/footer.component.html b/client/src/app/shared/components/footer/footer.component.html
index 6341b5818..77ac4279f 100644
--- a/client/src/app/shared/components/footer/footer.component.html
+++ b/client/src/app/shared/components/footer/footer.component.html
@@ -1,12 +1,12 @@
- Selected Values: + Selected values: