From dedf5caa1cd38c05a95df8e560690e6d972a99c7 Mon Sep 17 00:00:00 2001 From: "Jeroen van Meeuwen (Kolab Systems)" Date: Wed, 19 Dec 2018 10:05:30 +0100 Subject: [PATCH 01/98] No longer use de for de_DE --- .tx/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.tx/config b/.tx/config index 53e3e4f9..92b8df0f 100644 --- a/.tx/config +++ b/.tx/config @@ -1,6 +1,6 @@ [main] host = https://www.transifex.com -lang_map = en: en_US, de: de_DE, da: da_DK, es: es_ES, fi: fi_FI, fr: fr_FR, ja: ja_JP, nl: nl_NL, cs: cs_CZ, vi: vi_VN, th: th_TH, sv: sv_SE, he: he_IL, hr: hr_HR, sk: sk_SK, sl: sl_SI, uk: uk_UA +lang_map = en: en_US, da: da_DK, es: es_ES, fi: fi_FI, fr: fr_FR, ja: ja_JP, nl: nl_NL, cs: cs_CZ, vi: vi_VN, th: th_TH, sv: sv_SE, he: he_IL, hr: hr_HR, sk: sk_SK, sl: sl_SI, uk: uk_UA type = PHP_ALT_ARRAY [kolab.kolab_2fa] From 1e9692775fb991892fb48f2ee2bc2a04379cf38f Mon Sep 17 00:00:00 2001 From: "Jeroen van Meeuwen (Kolab Systems)" Date: Wed, 19 Dec 2018 10:07:51 +0100 Subject: [PATCH 02/98] New translation files --- .../locale/de/LC_MESSAGES/importexport.po | 99 +++++ .../helpdocs/locale/de/LC_MESSAGES/index.po | 29 ++ .../locale/de/LC_MESSAGES/invitations.po | 104 ++++++ .../helpdocs/locale/de/LC_MESSAGES/manage.po | 343 ++++++++++++++++++ .../locale/de/LC_MESSAGES/overview.po | 267 ++++++++++++++ .../locale/de/LC_MESSAGES/settings.po | 179 +++++++++ .../helpdocs/locale/de/LC_MESSAGES/sharing.po | 102 ++++++ .../locale/pl/LC_MESSAGES/importexport.po | 96 +++++ .../helpdocs/locale/pl/LC_MESSAGES/index.po | 28 ++ .../locale/pl/LC_MESSAGES/invitations.po | 103 ++++++ .../helpdocs/locale/pl/LC_MESSAGES/manage.po | 342 +++++++++++++++++ .../locale/pl/LC_MESSAGES/overview.po | 266 ++++++++++++++ .../locale/pl/LC_MESSAGES/settings.po | 178 +++++++++ .../helpdocs/locale/pl/LC_MESSAGES/sharing.po | 99 +++++ .../locale/de/LC_MESSAGES/addressbook.po | 81 +++++ .../locale/pl/LC_MESSAGES/addressbook.po | 78 ++++ .../helpdocs/locale/de/LC_MESSAGES/index.po | 29 ++ .../helpdocs/locale/de/LC_MESSAGES/manage.po | 325 +++++++++++++++++ .../locale/de/LC_MESSAGES/overview.po | 199 ++++++++++ .../helpdocs/locale/pl/LC_MESSAGES/index.po | 28 ++ .../helpdocs/locale/pl/LC_MESSAGES/manage.po | 323 +++++++++++++++++ .../locale/pl/LC_MESSAGES/overview.po | 198 ++++++++++ 22 files changed, 3496 insertions(+) create mode 100644 plugins/calendar/helpdocs/locale/de/LC_MESSAGES/importexport.po create mode 100644 plugins/calendar/helpdocs/locale/de/LC_MESSAGES/index.po create mode 100644 plugins/calendar/helpdocs/locale/de/LC_MESSAGES/invitations.po create mode 100644 plugins/calendar/helpdocs/locale/de/LC_MESSAGES/manage.po create mode 100644 plugins/calendar/helpdocs/locale/de/LC_MESSAGES/overview.po create mode 100644 plugins/calendar/helpdocs/locale/de/LC_MESSAGES/settings.po create mode 100644 plugins/calendar/helpdocs/locale/de/LC_MESSAGES/sharing.po create mode 100644 plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/importexport.po create mode 100644 plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/index.po create mode 100644 plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/invitations.po create mode 100644 plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/manage.po create mode 100644 plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/overview.po create mode 100644 plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/settings.po create mode 100644 plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/sharing.po create mode 100644 plugins/kolab_addressbook/helpdocs/locale/de/LC_MESSAGES/addressbook.po create mode 100644 plugins/kolab_addressbook/helpdocs/locale/pl/LC_MESSAGES/addressbook.po create mode 100644 plugins/tasklist/helpdocs/locale/de/LC_MESSAGES/index.po create mode 100644 plugins/tasklist/helpdocs/locale/de/LC_MESSAGES/manage.po create mode 100644 plugins/tasklist/helpdocs/locale/de/LC_MESSAGES/overview.po create mode 100644 plugins/tasklist/helpdocs/locale/pl/LC_MESSAGES/index.po create mode 100644 plugins/tasklist/helpdocs/locale/pl/LC_MESSAGES/manage.po create mode 100644 plugins/tasklist/helpdocs/locale/pl/LC_MESSAGES/overview.po diff --git a/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/importexport.po b/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/importexport.po new file mode 100644 index 00000000..0a6b450c --- /dev/null +++ b/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/importexport.po @@ -0,0 +1,99 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +# Ettore Atalan , 2014 +# Gerd Seyfarth , 2015 +# Jeroen van Meeuwen , 2016 +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2017-09-23 20:32+0000\n" +"Last-Translator: Jeroen van Meeuwen \n" +"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../en_US/_plugins/calendar/importexport.rst:9 +msgid "Import/Export" +msgstr "Importieren/Exportieren" + +#: ../../en_US/_plugins/calendar/importexport.rst:11 +msgid "" +"Event data is usually exchanged using the standard |iCal|_ format which is " +"supported for import and export." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:16 +msgid "Importing Events" +msgstr "Termine werden importiert" + +#: ../../en_US/_plugins/calendar/importexport.rst:18 +msgid "This is how to add events from an |iCal|_ (.ics) file:" +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:20 +msgid "Click the *Import* toolbar button in the calendar view." +msgstr "Klicken Sie in der Kalenderansicht auf die Werkzeugleistenschaltfläche *Import*." + +#: ../../en_US/_plugins/calendar/importexport.rst:21 +msgid "Then select the file to import from your computer's hard drive." +msgstr "Dann die Datei für den Import von Ihrer Festplatte wählen." + +#: ../../en_US/_plugins/calendar/importexport.rst:22 +msgid "Select the calendar to import the events to." +msgstr "Wählen Sie den Kalender zum Importieren der Termine aus." + +#: ../../en_US/_plugins/calendar/importexport.rst:23 +msgid "Select the threshold for old events to be imported." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:24 +msgid "Click *Import* and wait for the upload to finish." +msgstr "Klicken Sie auf *Import* und warten Sie, bis das Hochladen abgeschlossen ist." + +#: ../../en_US/_plugins/calendar/importexport.rst:26 +msgid "" +"The calendar view will be refreshed to display the newly imported events. " +"Verify that the according calendar is active if you don't see them." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:34 +msgid "Exporting Events" +msgstr "Termine werden exportiert" + +#: ../../en_US/_plugins/calendar/importexport.rst:36 +msgid "" +"Events from your calendars can be exported and downloaded in the |iCal|_ " +"format." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:38 +msgid "Click the *Export* toolbar button in the calendar view." +msgstr "Klicken Sie in der Kalenderansicht auf die Werkzeugleistenschaltfläche *Export*." + +#: ../../en_US/_plugins/calendar/importexport.rst:39 +msgid "Select the calendar where events should be exported from." +msgstr "Kalender wählen dessen Termine exportiert werden sollen." + +#: ../../en_US/_plugins/calendar/importexport.rst:40 +msgid "" +"With the *Events from* selector you choose the time constraints for " +"exporting." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:41 +msgid "Click the *Export* button to start the export." +msgstr "Klicken Sie auf die Schaltfläche *Export*, um den Export zu starten." + +#: ../../en_US/_plugins/calendar/importexport.rst:42 +msgid "" +"Choose where to save the exported .ics file if prompted, otherwise check the" +" \"Downloads\" folder on your computer." +msgstr "" diff --git a/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/index.po b/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/index.po new file mode 100644 index 00000000..4462b632 --- /dev/null +++ b/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/index.po @@ -0,0 +1,29 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +# Ettore Atalan , 2014 +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2017-09-23 20:32+0000\n" +"Last-Translator: Jeroen van Meeuwen \n" +"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../en_US/_plugins/calendar/index.rst:9 +msgid "Calendar" +msgstr "Kalender" + +#: ../../en_US/_plugins/calendar/index.rst:11 +msgid "" +"The *Calendar* gives you access to your personal and shared calendar and " +"scheduling functions." +msgstr "Der *Kalender* ermöglicht Ihnen den Zugriff auf Ihren persönlichen und den gemeinsamen Kalender sowie auf Planungsfunktionen." diff --git a/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/invitations.po b/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/invitations.po new file mode 100644 index 00000000..2bc6d6ef --- /dev/null +++ b/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/invitations.po @@ -0,0 +1,104 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +# Ettore Atalan , 2014 +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2017-09-23 20:32+0000\n" +"Last-Translator: Jeroen van Meeuwen \n" +"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../en_US/_plugins/calendar/invitations.rst:8 +msgid "Handle Event Invitations" +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:10 +msgid "" +"In chapter :ref:`calendar-event-participants` we have learned how to invite " +"other people to an event. This will send out invitation emails to all the " +"participants with the event data attached. That allows one to directly " +"accept or decline an event invitation." +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:17 +msgid "Receive Event Invitations" +msgstr "Termineinladungen erhalten" + +#: ../../en_US/_plugins/calendar/invitations.rst:19 +msgid "" +"When the webmail system opens an invitation email with event data attached, " +"it'll display a yellow box in the preview pane or the email view:" +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:25 +msgid "Accept/Decline Invitations" +msgstr "Einladungen annehmen/ablehnen" + +#: ../../en_US/_plugins/calendar/invitations.rst:27 +msgid "" +"Right in the box shown above, you can accept or decline the invitation by " +"clicking the according button. This will send an automated response to the " +"event organizer informing her about your decision and letting her update " +"your participant status in her calendar." +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:31 +msgid "" +"In case you accept, by either clicking *Accept* or *Maybe*, this will also " +"copy the event into your personal calendar. The selector right next to the " +"buttons lets you choose the right one." +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:35 +msgid "" +"The copy in your calendar now knows about the invitation and its original " +"sender. If you now delete it from your calendar, you'll be asked whether " +"this should send a declination message to the person who organizes the " +"event." +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:39 +msgid "" +"After acceping or declining, the email message containing the invitation can" +" be deleted." +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:43 +msgid "Process Invitation Replies" +msgstr "Einladungsantworten abarbeiten" + +#: ../../en_US/_plugins/calendar/invitations.rst:45 +msgid "" +"As an organizer who has invited others to an event, you'll receive responses" +" to the automatically sent invitations when the attendees either accept or " +"decline them." +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:48 +msgid "" +"Such messages are also identified by the webmail system and again a yellow " +"box appears in the message view:" +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:53 +msgid "" +"By clicking the *Update the participant's status* button, the original event" +" in your calendar will be updated with the RSVP status from the person who " +"responded here." +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:56 +msgid "" +"When you now look at the event details in the calendar view, the status " +"icons next to each participant now displays the new status." +msgstr "" diff --git a/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/manage.po b/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/manage.po new file mode 100644 index 00000000..ffdec701 --- /dev/null +++ b/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/manage.po @@ -0,0 +1,343 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +# Ettore Atalan , 2014 +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2017-09-23 20:32+0000\n" +"Last-Translator: Jeroen van Meeuwen \n" +"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../en_US/_plugins/calendar/manage.rst:7 +msgid "Manage Your Schedule" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:9 +msgid "" +"All functions to maintain your events are accessible from the main calendar " +"view." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:13 +msgid "Add Events to a Calendar" +msgstr "Termine zum Kalender hinzufügen" + +#: ../../en_US/_plugins/calendar/manage.rst:18 +msgid "**Via toolbar**" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:16 +msgid "" +"Click the *New event* button in the toolbar to get an empty dialog where you" +" enter the :ref:`event properties ` such as summary, " +"date/time, reminders, etc. Click *Save* to finally add it to the selected " +"calendar." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:27 +msgid "**At a specific date/time**" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:21 +msgid "" +"Navigate the calendar view to the date you want to add an event for. Then " +"mark the range of time (or dates in month view) with the mouse by pressing " +"the button at the time the event should start and releasing it again at time" +" it finishes. This will open the :ref:`event dialog ` " +"with the selected date/time range already filled in." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:26 +msgid "" +"In order to create new all-day events, double-click the desired day in the " +"calendar view." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:33 +msgid "Edit and Reschedule Events" +msgstr "Termine bearbeiten und verlegen" + +#: ../../en_US/_plugins/calendar/manage.rst:36 +msgid "The Event Dialog" +msgstr "Der Termindialog" + +#: ../../en_US/_plugins/calendar/manage.rst:38 +msgid "" +"When clicking an event in the calendar view, a dialog showing its details is" +" displayed. Clicking the *Edit* button in that dialog opens the form to edit" +" all properties of the selected event." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:41 +msgid "" +"The edit form is divided into different section which can be switched using " +"the tabs on top of the dialog:" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:44 +msgid "**Summary**" +msgstr "**Zusammenfassung**" + +#: ../../en_US/_plugins/calendar/manage.rst:46 +msgid "" +"This general section has text fields and selectors for various properties of" +" an event. Here's a description of all the possible values:" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:49 +msgid "" +"``Summary``: The title of the event. This is what you will see in the " +"calendar view." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:50 +msgid "``Location``: Where the event will be taking place." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:51 +msgid "``Description``: Any text that describes the event." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:52 +msgid "``URL``: A link to more information about this event." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:53 +msgid "``Start``: Date and time when the event starts." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:54 +msgid "``End``: Date and time when the event starts." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:55 +msgid "``all-day``: Check this if the event has no start/end time." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:56 +msgid "" +"``Reminder``: Will pop up with an notification at a the specified time " +"before the event." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:57 +msgid "" +"``Calendar``: The calendar the event is saved in. Change it to move an event" +" from one calendar to another." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:58 +msgid "" +"``Category``: The type of event. Categories can also be used for " +":ref:`coloring `." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:59 +msgid "" +"``Show me as``: The representation in your free/busy scheduling calendar " +"visible to others." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:60 +msgid "``Priority``: The priority value of the event." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:61 +msgid "" +"``Privacy``: Flag an event as \"private\" or \"confidential\" when sharing " +"your calendar with others." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:63 +msgid "**Recurrence**" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:65 +msgid "" +"For periodically recurring event series, this tabs has the settings how an " +"event is repeated over time." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:68 +msgid "``Repeat``: Start with selecting a repetition interval (e.g. monthly)" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:69 +msgid "" +"``Every``: How often the frequency will be relevant. For example, for an " +"event that takes place every other week choose Weekly and then 2. If you " +"choose a frequency of weekly or monthly you can select which days of the " +"week or month the event will occur." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:71 +msgid "" +"``Until``: Determines the duration of the repetition. The recurrence can " +"either run forever, for a number it times or until a specific date." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:73 +msgid "**Participants**" +msgstr "**Teilnehmer**" + +#: ../../en_US/_plugins/calendar/manage.rst:75 +msgid "" +"An important part of managing your schedule is to invite others to events " +"and track their RSVP. In this part of the edit dialog you can manage the " +"participants of an event. Read more about this further down in the :ref" +":`calendar-event-participants` section." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:79 +msgid "**Attachments**" +msgstr "**Anhänge**" + +#: ../../en_US/_plugins/calendar/manage.rst:81 +msgid "" +"Sometimes a description text isn't enough to collect information for a " +"specific event. Switch to this tab to attach files to the current event or " +"to remove them again. Adding files works pretty much the same as " +":ref:`attaching them to email messages `: first " +"select a file from your local disk and click *Upload* in order to attach it." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:86 +msgid "" +"Don't forget to finally save the changes by clicking *Save* in the event " +"edit dialog. Even switching back and forth the tabs will not yet save the " +"data." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:93 +msgid "Moving and Resizing with the Mouse" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:99 +msgid "" +"If an existing event shall be rescheduled to another time or date, you'll " +"find it handy to do that directly in the calendar view without opening the " +"edit form. Simply grab the event block with the mouse and move it to the new" +" date or time. Release the mouse button to complete." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:103 +msgid "" +"In *Month* and *Day* view, the event blocks have a small handle at the " +"bottom. Drag this with the mouse in order to resize the event meaning to " +"adjust its duration." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:111 +msgid "Get Notifications" +msgstr "Benachrichtigungen holen" + +#: ../../en_US/_plugins/calendar/manage.rst:117 +msgid "" +"While logged in to the webmail, event reminders will be displayed with pop-" +"up boxes at the specified time before the event starts. You can specify if " +"you want to see alarms for every calendar individually. Enable or disable " +"reminders in :ref:`Calendar Settings ` from the " +":ref:`calendar-lists`." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:122 +msgid "Dismiss or Snooze Reminders" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:124 +msgid "" +"When a reminder box pops up, you can either dismiss the notification for all" +" events or each one individually. When dismissed, no further reminders will " +"be displayed. Choose a time from the *Snooze* menu to get another reminder " +"after the selected time." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:133 +msgid "Inviting Other People" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:135 +msgid "" +"If you need to set up a meeting, and keep track of who's attending and who " +"is not, the calendar can do this as well as you to automatically send " +"invitations and read their responses." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:138 +msgid "" +"When creating a new event, switch to the *Participants* tab. You're already " +"listed as the organizer of the event." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:142 +msgid "" +"Enter the name or email address of the person to invite. Contacts from the " +"address book are suggested as you type. In order to send invitations, make " +"sure the entered contact has an email address. Type it in the form ``Person " +"Name ``." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:145 +msgid "Click *Add participant* to add the person to the list." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:146 +msgid "Select a *Role* (e.g. required or optional) for this person." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:147 +msgid "Repeat 1-3 for further participants." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:148 +msgid "" +"Check the *Send invitations* box if the application should send out " +"invitation emails." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:150 +msgid "" +"Invitations will be sent out when you click *Save* and the event is created." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:158 +msgid "Find Availability" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:160 +msgid "" +"Once all the participants are added to the list, you see the individual " +"availability status for each one of them, given that this information is " +"available. In case not everybody is free, click the *Find availability...* " +"button to open the scheduling dialog. In that dialog, detailed availability " +"information for all participants is displayed. Use the *Previous/Next Slot* " +"buttons to find the next time slot where all required participants are " +"available. Or drag the gray area representing the event duration with the " +"mouse to manually select a free slot." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:166 +msgid "" +"Click *Select* to copy the rescheduled date/time back into the event form " +"and to close this dialog." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:170 +msgid "Receive Event Invitations" +msgstr "Termineinladungen erhalten" + +#: ../../en_US/_plugins/calendar/manage.rst:172 +msgid "" +"How to process incoming event invitations is described in chapter :ref" +":`calendar-invitations`." +msgstr "" diff --git a/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/overview.po b/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/overview.po new file mode 100644 index 00000000..5e6f0dc6 --- /dev/null +++ b/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/overview.po @@ -0,0 +1,267 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +# Ettore Atalan , 2014 +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2017-09-23 20:32+0000\n" +"Last-Translator: Jeroen van Meeuwen \n" +"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../en_US/_plugins/calendar/overview.rst:6 +msgid "Overview" +msgstr "Übersicht" + +#: ../../en_US/_plugins/calendar/overview.rst:8 +msgid "" +"The screen of the calendar module presents the following parts: the " +":ref:`Calendar View ` itself, a small :ref:`Calendar Widget " +"` the :ref:`calendar-lists` as well as the usual " +"toolbar and search box." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:17 +msgid "Calendar View" +msgstr "Kalenderansicht" + +#: ../../en_US/_plugins/calendar/overview.rst:19 +msgid "" +"The central part of the screen displays the schedule with events from the " +"active calendars matching the current date range. The active date range is " +"displayed above the calendar in the toolbar area and can be moved forward or" +" backward in time using the arrow buttons right next to the title." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:27 +msgid "Change Views" +msgstr "Ansichten ändern" + +#: ../../en_US/_plugins/calendar/overview.rst:29 +msgid "" +"You can view your calendar events in Day, Week, Month or Agenda view. Toggle" +" the view mode using the toolbar buttons above the calendar view." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:34 +msgid "**Day**" +msgstr "**Tag**" + +#: ../../en_US/_plugins/calendar/overview.rst:33 +msgid "" +"All events of a single day appear at the time the begin and spawn a box " +"until their end time. The time scale is displayed in the left side of the " +"view. All-day events appear at the top." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:37 +msgid "**Week**" +msgstr "**Woche**" + +#: ../../en_US/_plugins/calendar/overview.rst:37 +msgid "" +"Similar to the day view but lists all days of the week horizontally. All-day" +" events again appear at the top." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:42 +msgid "**Month**" +msgstr "**Monat**" + +#: ../../en_US/_plugins/calendar/overview.rst:40 +msgid "" +"Shows all events of the selected month at a time. Each event only appears as" +" a single line and if there are more events in a day than can be listed, a " +"number at the bottom of the day field indicates that. Click that link to " +"open a zoomed view of that single day." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:47 +msgid "**Agenda**" +msgstr "**Tagesordnung**" + +#: ../../en_US/_plugins/calendar/overview.rst:45 +msgid "" +"The agenda view shows a list of events for the selected range in a " +"chronological order and divided by headers denoting either days, weeks or " +"months. Both the number of the days considered for the listing as well as " +"the mode how to divide list can be adjusted with the controls at the bottom " +"of the agenda view." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:51 +msgid "" +"For all the views, the small calendar on the left highlights the currently " +"listed days." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:54 +msgid "Go to a specific Date" +msgstr "Zu einem bestimmten Datum gehen" + +#: ../../en_US/_plugins/calendar/overview.rst:56 +msgid "" +"Use the mini calendar widget on the left to jump to a specific date. Simply " +"click a date and the date range of the current view moves to include the " +"selected day. The left/right arrows in the mini calendar's header quickly " +"cycle through the months. Use the drop-down menus hidden under the month and" +" year display in the widget header to directly jump to another month or " +"year." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:60 +msgid "" +"A shortcut to switch the calendar view back to today or the current week " +"provides the *Today* button located in the toolbar." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:64 +msgid "Show Event Details" +msgstr "Termindetails anzeigen" + +#: ../../en_US/_plugins/calendar/overview.rst:66 +msgid "" +"Click an event box in the calendar view to open a dialog displaying all " +"details of the event." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:70 +msgid "Searching Events" +msgstr "Terminsuche" + +#: ../../en_US/_plugins/calendar/overview.rst:72 +msgid "" +"The search box above the calendar view lets you quickly get a list of events" +" matching the entered keyword in either the title, location, description or " +"attendees. Enter the search term into the box and press on your " +"keyboard to start the search. The calendar view will switch to *Agenda* mode" +" in order to display a list of matches. Of course you can switch the view " +"again to display the search results differently." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:77 +msgid "" +"Events are searched within a certain date reange only which is displayed " +"above the calendar view. Use the mini calendar widget or the arrow toolbar " +"buttons and the range selector below the agenda view to adjust the time " +"frame to search in." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:81 +msgid "" +"For searching as well as for normal views, only events from active calendars" +" are displayed. Use the checkboxes in the :ref:`calendar-lists` to add or " +"hide events from different calendars." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:84 +msgid "" +"Reset the search by clicking the *Reset search* icon on the right border of " +"the search box. This will also switch the calendar view to whatever mode you" +" had before the search." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:93 +msgid "Calendars List" +msgstr "Kalenderliste" + +#: ../../en_US/_plugins/calendar/overview.rst:95 +msgid "" +"Events can be organized in different calendars which are all displayed in " +"the lower left list. Use the checkboxes in that list to show or hide events " +"from the specific calendars in the main view." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:100 +msgid "" +"Beside your personal calendars, the list also displays calendars shared by " +"other users or ones that are shared amongst your workgroup. Small icons in " +"the list give a hint about the origin and some of them are possibly read-" +"only which is denoted with a small lock icon." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:106 +msgid "Colorized Events" +msgstr "Eingefärbte Termine" + +#: ../../en_US/_plugins/calendar/overview.rst:108 +msgid "" +"In order to better distinguish the events from various calendars in the " +"calendar view, calendars have a color assigned which is used to colorize the" +" events on the screen. Check the :ref:`settings-calendar` for more advanced " +"options how to colorize events in the calendar view." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:112 +msgid "" +"You can create any number of calendars to store all your events and name " +"them individually." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:116 +msgid "Create a New Calendar" +msgstr "Einen neuen Kalender erstellen" + +#: ../../en_US/_plugins/calendar/overview.rst:118 +msgid "Click the + icon in the calendars list footer." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:119 +msgid "In the dialog, give the new calendar a unique name and assign a color." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:120 +msgid "Click *Save* to create it." +msgstr "Klicken Sie auf *Speichern* zum Erstellen." + +#: ../../en_US/_plugins/calendar/overview.rst:122 +msgid "The calendar view will reload and list the new calendar on the left." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:127 +msgid "Edit Calendar Names and Settings" +msgstr "Kalendernamen und Einstellungen bearbeiten" + +#: ../../en_US/_plugins/calendar/overview.rst:129 +#: ../../en_US/_plugins/calendar/overview.rst:137 +msgid "Select the calendar to edit by clicking it in the list." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:130 +msgid "" +"Click the gear icon in the calendars list footer and select *Edit* from the " +"options menu." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:131 +msgid "Adjust name, color or reminders settings in the edit dialog." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:132 +msgid "Click *Save* to finally update the calendar." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:135 +msgid "Remove entire Calendars" +msgstr "Gesamte Kalender entfernen" + +#: ../../en_US/_plugins/calendar/overview.rst:138 +msgid "" +"Click the gear icon in the calendars list footer and select *Remove* from " +"the options menu." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:139 +msgid "" +"After a confirmation dialog, the selected calendar with all its events will " +"be deleted. Caution: This action cannot be undone!" +msgstr "" diff --git a/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/settings.po b/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/settings.po new file mode 100644 index 00000000..298df039 --- /dev/null +++ b/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/settings.po @@ -0,0 +1,179 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +# Ettore Atalan , 2014 +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2017-09-23 20:32+0000\n" +"Last-Translator: Jeroen van Meeuwen \n" +"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../en_US/_plugins/calendar/settings.rst:8 +msgid "Calendar Preferences" +msgstr "Kalendereinstellungen" + +#: ../../en_US/_plugins/calendar/settings.rst:10 +msgid "" +"The settings for the calendar module are listed in *Settings > Preferences* " +"and are grouped by the following sections:" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:14 +msgid "Main Options" +msgstr "Hauptoptionen" + +#: ../../en_US/_plugins/calendar/settings.rst:17 +msgid "**Default view**" +msgstr "**Standardansicht**" + +#: ../../en_US/_plugins/calendar/settings.rst:17 +msgid "" +"Lets you select the :ref:`calendar-view` which is visible by default when " +"opening the calendar." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:21 +msgid "**Time slots per hour**" +msgstr "**Zeitfenster pro Stunde**" + +#: ../../en_US/_plugins/calendar/settings.rst:20 +msgid "" +"How one hour in day and week view is divided vertically. If for example set " +"to 2, you will see events displayed in 30 minute blocks." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:24 +msgid "**First weekday**" +msgstr "**Erster Wochentag**" + +#: ../../en_US/_plugins/calendar/settings.rst:24 +msgid "Which weekday to begin the week view with." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:28 +msgid "**First hour to show**" +msgstr "**Erste angezeigte Stunde**" + +#: ../../en_US/_plugins/calendar/settings.rst:27 +msgid "" +"When opening the day or week view, the listing of events starts at this " +"time. Of course all hours of a day are visible by scrolling further up." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:33 +msgid "**Working hours**" +msgstr "**Arbeitszeiten**" + +#: ../../en_US/_plugins/calendar/settings.rst:33 +msgid "" +"This time range will be used in the :ref:`availability finder ` when automatically selecting free slots for a meeting." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:40 +msgid "**Event coloring**" +msgstr "**Einfärbung der Termine**" + +#: ../../en_US/_plugins/calendar/settings.rst:37 +msgid "" +"The coloring of the title of an event block (\"outline\") as well as the " +"background color of the box (\"content\") in day and week views is " +"influenced by the color of the calendar an event belongs to and/or the color" +" of the category it is assigned to. This setting lets you control which " +"source for coloring to use or if you even want a combined coloring that " +"reflects both, the assignment of calendars and categories." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:43 +msgid "**Default reminder setting**" +msgstr "**Standard-Erinnerungseinstellung**" + +#: ../../en_US/_plugins/calendar/settings.rst:43 +msgid "" +"When creating new events, they'll have this type of reminder set by default." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:46 +msgid "**Default reminder time**" +msgstr "**Standard-Erinnerungszeit**" + +#: ../../en_US/_plugins/calendar/settings.rst:46 +msgid "When enabling reminders in a new event, use this preset as default." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:51 +msgid "**Create new events in**" +msgstr "**Neue Termine erstellen in**" + +#: ../../en_US/_plugins/calendar/settings.rst:49 +msgid "" +"This is the default selection for saving new events. Used in both the " +"calendar view and when accepting event invitations." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:54 +msgid "Categories" +msgstr "Kategorien" + +#: ../../en_US/_plugins/calendar/settings.rst:56 +msgid "" +"This block allows the management of categories used in your calendar and " +"assign colors to them. Use the color picker to change the color by clicking " +"on the square color box in the categories list." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:59 +msgid "" +"To add a new category, enter its unique name into the text box below the " +"listing and then click the *Add category** button to add it. Note that you " +"still need to click the *Save* button at the bottom of the preferences panel" +" in order to finally register the new categories." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:65 +msgid "Birthdays Calendar" +msgstr "Geburtstagskalender" + +#: ../../en_US/_plugins/calendar/settings.rst:67 +msgid "" +"The calendar view and also display birthdays from contacts saved in your " +"address book. This block controls how this is done." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:71 +msgid "**Display birthdays calendar**" +msgstr "**Geburtstagskalender anzeigen**" + +#: ../../en_US/_plugins/calendar/settings.rst:71 +msgid "Enable the birthdays calendar feature with this checkbox." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:74 +msgid "**From these address books**" +msgstr "**Von diesen Adressbüchern**" + +#: ../../en_US/_plugins/calendar/settings.rst:74 +msgid "" +"Choose from which address books you'd like to see birthdays in your " +"calendar." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:80 +msgid "**Show reminders**" +msgstr "**Erinnerungen anzeigen**" + +#: ../../en_US/_plugins/calendar/settings.rst:77 +msgid "" +"This option controls whether and when to display reminder notifications for " +"upcoming birthdays." +msgstr "" diff --git a/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/sharing.po b/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/sharing.po new file mode 100644 index 00000000..43ac9df3 --- /dev/null +++ b/plugins/calendar/helpdocs/locale/de/LC_MESSAGES/sharing.po @@ -0,0 +1,102 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +# Ettore Atalan , 2014 +# Mads , 2016 +# Max Hellwig , 2016 +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2017-09-23 20:32+0000\n" +"Last-Translator: Max Hellwig \n" +"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../en_US/_plugins/calendar/sharing.rst:11 +msgid "Sharing Calendars" +msgstr "Kalender teilen" + +#: ../../en_US/_plugins/calendar/sharing.rst:13 +msgid "" +"For collaboration, sharing calendars is an important feature. In the " +":ref:`overview `, we have already learned how calendars " +"others share with you appear in the calendars list. The following now " +"explains how to make personal calendars accessible to fellow users." +msgstr "Kalender zu teilen ist ein wichtiger Teil der Zusammenarbeit. In der :ref:`Übersicht ` haben wir schon gelernt, wie Kalender, die von anderen mit Ihnen teilen, in der Kalenderliste aussehen. Im Folgenden wird jetzt erklärt wie man persönliche Kalender für andere Benutzer zugänglich macht." + +#: ../../en_US/_plugins/calendar/sharing.rst:19 +msgid "Share a Calendar with others" +msgstr "Einen Kalender mit Anderen teilen" + +#: ../../en_US/_plugins/calendar/sharing.rst:21 +msgid "" +"Sharing is controlled through the :ref:`Calendar Settings Dialog `. Double-click a calendar in the list on the left and then " +"select the *Sharing* tab at the top of the dialog box:" +msgstr "Das Teilen wird über den :ref:`Kalendereinstellungen-Dialog ` gesteuert. Doppelklicken Sie einen Kalenders in der Liste links und wählen dann den *Teilen*-Reiter im oberen Teil des Dialogfensters aus:" + +#: ../../en_US/_plugins/calendar/sharing.rst:27 +msgid "" +"The table displays who already has permission to see and modify the selected" +" calendar. In order to share the calendar with a new user do" +msgstr "Die Tabelle zeigt an, wer schon Erlaubnis hat, den ausgewählten Kalender zu sehen und verändern. Um den Kalender mit einem neuen Benutzer zu teilen," + +#: ../../en_US/_plugins/calendar/sharing.rst:30 +msgid "Click the *Add entry* button (+) in the table footer" +msgstr "klicken Sie auf die *Eintrag hinzufügen*-Schaltfläche (+) in der Fußzeile der Tabelle." + +#: ../../en_US/_plugins/calendar/sharing.rst:31 +msgid "" +"Enter the username or choose one from the autocompletion menu that appears " +"when you start typing. Instead of a specific user, permissons can be granted" +" for all users or guests." +msgstr "Geben Sie den Benutzername ein oder wählen Sie einen aus dem Autovervollständigungs-Menü aus, das erscheint, wenn Sie zu tippen beginnen. Statt einem bestimmten Benutzer können Erlaubnisse auch allen Benutzern oder Gästen gewährt werden." + +#: ../../en_US/_plugins/calendar/sharing.rst:33 +msgid "Select the access rights you want to grant for the user" +msgstr "Wählen Sie die Zugangsberechtigungen, die Sie dem Benutzer gewähren wollen." + +#: ../../en_US/_plugins/calendar/sharing.rst:34 +msgid "Click *Save* to add the permission" +msgstr "Klicken Sie auf *Speichern*, um die Erlaubnis hinzuzufügen." + +#: ../../en_US/_plugins/calendar/sharing.rst:36 +msgid "" +"Double-click an entry to edit the permissions for a particular user or " +"group." +msgstr "Doppelklicken Sie einen Eintrag, um Erlaubnisse für einen bestimmten Benutzer oder eine bestimmte Gruppe zu bearbeiten." + +#: ../../en_US/_plugins/calendar/sharing.rst:38 +msgid "" +"For removing existing permissions, select the according entry in the list " +"and then choose *Delete* from the menu behind the gear icon in the footer of" +" the list." +msgstr "Um bestehende Freigaben zu entfernen, wählen Sie den entsprechenden Eintrag in der Liste aus und wählen dann *Löschen* aus dem Menü hinter dem Zahnradicon in der Fußzeile der Liste aus." + +#: ../../en_US/_plugins/calendar/sharing.rst:43 +msgid "Subscribe to Shared Calendars" +msgstr "Geteilte Kalender abonnieren" + +#: ../../en_US/_plugins/calendar/sharing.rst:45 +msgid "" +"Calendars shared by others are not showing up right away in the list within " +"the calendar view. Switch to :ref:`Settings > Folders ` to" +" see all resources you can access. There's a shortcut to this: click *Manage" +" folders* in the options menu behind the gear icon located the footer of the" +" calendars list." +msgstr "Von anderen geteilte Kalender tauchen nicht sofort in der Liste innerhalb der Kalenderansicht auf. Wechseln Sie zu :ref:`Einstellungen > Ordner `, um alle Hilfsmittel zu sehen, auf die Sie zugreifen können. Es gibt auch einen kürzeren Weg dorthin: Klicken Sie auf *Ordner verwalten* im Optionsmenü hinter dem Zahnradicon in der Fußzeile der Kalenderliste." + +#: ../../en_US/_plugins/calendar/sharing.rst:50 +msgid "" +"In order to make a shared calendar appear in the calendars list, locate it " +"in the folder manager and check the *Subscribed* mark in the list. Only " +"subscribed calendars are visible in the calendar view." +msgstr "Um einen geteilten Kalender in der Kalenderliste erscheinen zu lassen, suchen Sie ihn in der Ordnerverwaltung und versehen Sie das *Abonniert*-Kästchen in der Liste mit einem Häkchen. Nur abonnierte Kalender sind in der Kalenderansicht sichtbar." diff --git a/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/importexport.po b/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/importexport.po new file mode 100644 index 00000000..6dad617b --- /dev/null +++ b/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/importexport.po @@ -0,0 +1,96 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2014-11-27 23:33+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Polish (http://www.transifex.com/kolab/kolab-documentation/language/pl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pl\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" + +#: ../../en_US/_plugins/calendar/importexport.rst:9 +msgid "Import/Export" +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:11 +msgid "" +"Event data is usually exchanged using the standard |iCal|_ format which is " +"supported for import and export." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:16 +msgid "Importing Events" +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:18 +msgid "This is how to add events from an |iCal|_ (.ics) file:" +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:20 +msgid "Click the *Import* toolbar button in the calendar view." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:21 +msgid "Then select the file to import from your computer's hard drive." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:22 +msgid "Select the calendar to import the events to." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:23 +msgid "Select the threshold for old events to be imported." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:24 +msgid "Click *Import* and wait for the upload to finish." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:26 +msgid "" +"The calendar view will be refreshed to display the newly imported events. " +"Verify that the according calendar is active if you don't see them." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:34 +msgid "Exporting Events" +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:36 +msgid "" +"Events from your calendars can be exported and downloaded in the |iCal|_ " +"format." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:38 +msgid "Click the *Export* toolbar button in the calendar view." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:39 +msgid "Select the calendar where events should be exported from." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:40 +msgid "" +"With the *Events from* selector you choose the time constraints for " +"exporting." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:41 +msgid "Click the *Export* button to start the export." +msgstr "" + +#: ../../en_US/_plugins/calendar/importexport.rst:42 +msgid "" +"Choose where to save the exported .ics file if prompted, otherwise check the" +" \"Downloads\" folder on your computer." +msgstr "" diff --git a/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/index.po b/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/index.po new file mode 100644 index 00000000..f5c92fb6 --- /dev/null +++ b/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/index.po @@ -0,0 +1,28 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2014-11-27 23:33+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Polish (http://www.transifex.com/kolab/kolab-documentation/language/pl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pl\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" + +#: ../../en_US/_plugins/calendar/index.rst:9 +msgid "Calendar" +msgstr "" + +#: ../../en_US/_plugins/calendar/index.rst:11 +msgid "" +"The *Calendar* gives you access to your personal and shared calendar and " +"scheduling functions." +msgstr "" diff --git a/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/invitations.po b/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/invitations.po new file mode 100644 index 00000000..74527065 --- /dev/null +++ b/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/invitations.po @@ -0,0 +1,103 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2014-11-27 23:33+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Polish (http://www.transifex.com/kolab/kolab-documentation/language/pl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pl\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" + +#: ../../en_US/_plugins/calendar/invitations.rst:8 +msgid "Handle Event Invitations" +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:10 +msgid "" +"In chapter :ref:`calendar-event-participants` we have learned how to invite " +"other people to an event. This will send out invitation emails to all the " +"participants with the event data attached. That allows one to directly " +"accept or decline an event invitation." +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:17 +msgid "Receive Event Invitations" +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:19 +msgid "" +"When the webmail system opens an invitation email with event data attached, " +"it'll display a yellow box in the preview pane or the email view:" +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:25 +msgid "Accept/Decline Invitations" +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:27 +msgid "" +"Right in the box shown above, you can accept or decline the invitation by " +"clicking the according button. This will send an automated response to the " +"event organizer informing her about your decision and letting her update " +"your participant status in her calendar." +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:31 +msgid "" +"In case you accept, by either clicking *Accept* or *Maybe*, this will also " +"copy the event into your personal calendar. The selector right next to the " +"buttons lets you choose the right one." +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:35 +msgid "" +"The copy in your calendar now knows about the invitation and its original " +"sender. If you now delete it from your calendar, you'll be asked whether " +"this should send a declination message to the person who organizes the " +"event." +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:39 +msgid "" +"After acceping or declining, the email message containing the invitation can" +" be deleted." +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:43 +msgid "Process Invitation Replies" +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:45 +msgid "" +"As an organizer who has invited others to an event, you'll receive responses" +" to the automatically sent invitations when the attendees either accept or " +"decline them." +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:48 +msgid "" +"Such messages are also identified by the webmail system and again a yellow " +"box appears in the message view:" +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:53 +msgid "" +"By clicking the *Update the participant's status* button, the original event" +" in your calendar will be updated with the RSVP status from the person who " +"responded here." +msgstr "" + +#: ../../en_US/_plugins/calendar/invitations.rst:56 +msgid "" +"When you now look at the event details in the calendar view, the status " +"icons next to each participant now displays the new status." +msgstr "" diff --git a/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/manage.po b/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/manage.po new file mode 100644 index 00000000..68fd8a48 --- /dev/null +++ b/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/manage.po @@ -0,0 +1,342 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2014-11-27 23:33+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Polish (http://www.transifex.com/kolab/kolab-documentation/language/pl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pl\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" + +#: ../../en_US/_plugins/calendar/manage.rst:7 +msgid "Manage Your Schedule" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:9 +msgid "" +"All functions to maintain your events are accessible from the main calendar " +"view." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:13 +msgid "Add Events to a Calendar" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:18 +msgid "**Via toolbar**" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:16 +msgid "" +"Click the *New event* button in the toolbar to get an empty dialog where you" +" enter the :ref:`event properties ` such as summary, " +"date/time, reminders, etc. Click *Save* to finally add it to the selected " +"calendar." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:27 +msgid "**At a specific date/time**" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:21 +msgid "" +"Navigate the calendar view to the date you want to add an event for. Then " +"mark the range of time (or dates in month view) with the mouse by pressing " +"the button at the time the event should start and releasing it again at time" +" it finishes. This will open the :ref:`event dialog ` " +"with the selected date/time range already filled in." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:26 +msgid "" +"In order to create new all-day events, double-click the desired day in the " +"calendar view." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:33 +msgid "Edit and Reschedule Events" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:36 +msgid "The Event Dialog" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:38 +msgid "" +"When clicking an event in the calendar view, a dialog showing its details is" +" displayed. Clicking the *Edit* button in that dialog opens the form to edit" +" all properties of the selected event." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:41 +msgid "" +"The edit form is divided into different section which can be switched using " +"the tabs on top of the dialog:" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:44 +msgid "**Summary**" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:46 +msgid "" +"This general section has text fields and selectors for various properties of" +" an event. Here's a description of all the possible values:" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:49 +msgid "" +"``Summary``: The title of the event. This is what you will see in the " +"calendar view." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:50 +msgid "``Location``: Where the event will be taking place." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:51 +msgid "``Description``: Any text that describes the event." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:52 +msgid "``URL``: A link to more information about this event." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:53 +msgid "``Start``: Date and time when the event starts." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:54 +msgid "``End``: Date and time when the event starts." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:55 +msgid "``all-day``: Check this if the event has no start/end time." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:56 +msgid "" +"``Reminder``: Will pop up with an notification at a the specified time " +"before the event." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:57 +msgid "" +"``Calendar``: The calendar the event is saved in. Change it to move an event" +" from one calendar to another." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:58 +msgid "" +"``Category``: The type of event. Categories can also be used for " +":ref:`coloring `." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:59 +msgid "" +"``Show me as``: The representation in your free/busy scheduling calendar " +"visible to others." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:60 +msgid "``Priority``: The priority value of the event." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:61 +msgid "" +"``Privacy``: Flag an event as \"private\" or \"confidential\" when sharing " +"your calendar with others." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:63 +msgid "**Recurrence**" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:65 +msgid "" +"For periodically recurring event series, this tabs has the settings how an " +"event is repeated over time." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:68 +msgid "``Repeat``: Start with selecting a repetition interval (e.g. monthly)" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:69 +msgid "" +"``Every``: How often the frequency will be relevant. For example, for an " +"event that takes place every other week choose Weekly and then 2. If you " +"choose a frequency of weekly or monthly you can select which days of the " +"week or month the event will occur." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:71 +msgid "" +"``Until``: Determines the duration of the repetition. The recurrence can " +"either run forever, for a number it times or until a specific date." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:73 +msgid "**Participants**" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:75 +msgid "" +"An important part of managing your schedule is to invite others to events " +"and track their RSVP. In this part of the edit dialog you can manage the " +"participants of an event. Read more about this further down in the :ref" +":`calendar-event-participants` section." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:79 +msgid "**Attachments**" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:81 +msgid "" +"Sometimes a description text isn't enough to collect information for a " +"specific event. Switch to this tab to attach files to the current event or " +"to remove them again. Adding files works pretty much the same as " +":ref:`attaching them to email messages `: first " +"select a file from your local disk and click *Upload* in order to attach it." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:86 +msgid "" +"Don't forget to finally save the changes by clicking *Save* in the event " +"edit dialog. Even switching back and forth the tabs will not yet save the " +"data." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:93 +msgid "Moving and Resizing with the Mouse" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:99 +msgid "" +"If an existing event shall be rescheduled to another time or date, you'll " +"find it handy to do that directly in the calendar view without opening the " +"edit form. Simply grab the event block with the mouse and move it to the new" +" date or time. Release the mouse button to complete." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:103 +msgid "" +"In *Month* and *Day* view, the event blocks have a small handle at the " +"bottom. Drag this with the mouse in order to resize the event meaning to " +"adjust its duration." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:111 +msgid "Get Notifications" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:117 +msgid "" +"While logged in to the webmail, event reminders will be displayed with pop-" +"up boxes at the specified time before the event starts. You can specify if " +"you want to see alarms for every calendar individually. Enable or disable " +"reminders in :ref:`Calendar Settings ` from the " +":ref:`calendar-lists`." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:122 +msgid "Dismiss or Snooze Reminders" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:124 +msgid "" +"When a reminder box pops up, you can either dismiss the notification for all" +" events or each one individually. When dismissed, no further reminders will " +"be displayed. Choose a time from the *Snooze* menu to get another reminder " +"after the selected time." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:133 +msgid "Inviting Other People" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:135 +msgid "" +"If you need to set up a meeting, and keep track of who's attending and who " +"is not, the calendar can do this as well as you to automatically send " +"invitations and read their responses." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:138 +msgid "" +"When creating a new event, switch to the *Participants* tab. You're already " +"listed as the organizer of the event." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:142 +msgid "" +"Enter the name or email address of the person to invite. Contacts from the " +"address book are suggested as you type. In order to send invitations, make " +"sure the entered contact has an email address. Type it in the form ``Person " +"Name ``." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:145 +msgid "Click *Add participant* to add the person to the list." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:146 +msgid "Select a *Role* (e.g. required or optional) for this person." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:147 +msgid "Repeat 1-3 for further participants." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:148 +msgid "" +"Check the *Send invitations* box if the application should send out " +"invitation emails." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:150 +msgid "" +"Invitations will be sent out when you click *Save* and the event is created." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:158 +msgid "Find Availability" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:160 +msgid "" +"Once all the participants are added to the list, you see the individual " +"availability status for each one of them, given that this information is " +"available. In case not everybody is free, click the *Find availability...* " +"button to open the scheduling dialog. In that dialog, detailed availability " +"information for all participants is displayed. Use the *Previous/Next Slot* " +"buttons to find the next time slot where all required participants are " +"available. Or drag the gray area representing the event duration with the " +"mouse to manually select a free slot." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:166 +msgid "" +"Click *Select* to copy the rescheduled date/time back into the event form " +"and to close this dialog." +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:170 +msgid "Receive Event Invitations" +msgstr "" + +#: ../../en_US/_plugins/calendar/manage.rst:172 +msgid "" +"How to process incoming event invitations is described in chapter :ref" +":`calendar-invitations`." +msgstr "" diff --git a/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/overview.po b/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/overview.po new file mode 100644 index 00000000..924633c7 --- /dev/null +++ b/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/overview.po @@ -0,0 +1,266 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2014-11-27 23:33+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Polish (http://www.transifex.com/kolab/kolab-documentation/language/pl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pl\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" + +#: ../../en_US/_plugins/calendar/overview.rst:6 +msgid "Overview" +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:8 +msgid "" +"The screen of the calendar module presents the following parts: the " +":ref:`Calendar View ` itself, a small :ref:`Calendar Widget " +"` the :ref:`calendar-lists` as well as the usual " +"toolbar and search box." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:17 +msgid "Calendar View" +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:19 +msgid "" +"The central part of the screen displays the schedule with events from the " +"active calendars matching the current date range. The active date range is " +"displayed above the calendar in the toolbar area and can be moved forward or" +" backward in time using the arrow buttons right next to the title." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:27 +msgid "Change Views" +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:29 +msgid "" +"You can view your calendar events in Day, Week, Month or Agenda view. Toggle" +" the view mode using the toolbar buttons above the calendar view." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:34 +msgid "**Day**" +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:33 +msgid "" +"All events of a single day appear at the time the begin and spawn a box " +"until their end time. The time scale is displayed in the left side of the " +"view. All-day events appear at the top." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:37 +msgid "**Week**" +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:37 +msgid "" +"Similar to the day view but lists all days of the week horizontally. All-day" +" events again appear at the top." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:42 +msgid "**Month**" +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:40 +msgid "" +"Shows all events of the selected month at a time. Each event only appears as" +" a single line and if there are more events in a day than can be listed, a " +"number at the bottom of the day field indicates that. Click that link to " +"open a zoomed view of that single day." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:47 +msgid "**Agenda**" +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:45 +msgid "" +"The agenda view shows a list of events for the selected range in a " +"chronological order and divided by headers denoting either days, weeks or " +"months. Both the number of the days considered for the listing as well as " +"the mode how to divide list can be adjusted with the controls at the bottom " +"of the agenda view." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:51 +msgid "" +"For all the views, the small calendar on the left highlights the currently " +"listed days." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:54 +msgid "Go to a specific Date" +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:56 +msgid "" +"Use the mini calendar widget on the left to jump to a specific date. Simply " +"click a date and the date range of the current view moves to include the " +"selected day. The left/right arrows in the mini calendar's header quickly " +"cycle through the months. Use the drop-down menus hidden under the month and" +" year display in the widget header to directly jump to another month or " +"year." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:60 +msgid "" +"A shortcut to switch the calendar view back to today or the current week " +"provides the *Today* button located in the toolbar." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:64 +msgid "Show Event Details" +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:66 +msgid "" +"Click an event box in the calendar view to open a dialog displaying all " +"details of the event." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:70 +msgid "Searching Events" +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:72 +msgid "" +"The search box above the calendar view lets you quickly get a list of events" +" matching the entered keyword in either the title, location, description or " +"attendees. Enter the search term into the box and press on your " +"keyboard to start the search. The calendar view will switch to *Agenda* mode" +" in order to display a list of matches. Of course you can switch the view " +"again to display the search results differently." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:77 +msgid "" +"Events are searched within a certain date reange only which is displayed " +"above the calendar view. Use the mini calendar widget or the arrow toolbar " +"buttons and the range selector below the agenda view to adjust the time " +"frame to search in." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:81 +msgid "" +"For searching as well as for normal views, only events from active calendars" +" are displayed. Use the checkboxes in the :ref:`calendar-lists` to add or " +"hide events from different calendars." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:84 +msgid "" +"Reset the search by clicking the *Reset search* icon on the right border of " +"the search box. This will also switch the calendar view to whatever mode you" +" had before the search." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:93 +msgid "Calendars List" +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:95 +msgid "" +"Events can be organized in different calendars which are all displayed in " +"the lower left list. Use the checkboxes in that list to show or hide events " +"from the specific calendars in the main view." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:100 +msgid "" +"Beside your personal calendars, the list also displays calendars shared by " +"other users or ones that are shared amongst your workgroup. Small icons in " +"the list give a hint about the origin and some of them are possibly read-" +"only which is denoted with a small lock icon." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:106 +msgid "Colorized Events" +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:108 +msgid "" +"In order to better distinguish the events from various calendars in the " +"calendar view, calendars have a color assigned which is used to colorize the" +" events on the screen. Check the :ref:`settings-calendar` for more advanced " +"options how to colorize events in the calendar view." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:112 +msgid "" +"You can create any number of calendars to store all your events and name " +"them individually." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:116 +msgid "Create a New Calendar" +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:118 +msgid "Click the + icon in the calendars list footer." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:119 +msgid "In the dialog, give the new calendar a unique name and assign a color." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:120 +msgid "Click *Save* to create it." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:122 +msgid "The calendar view will reload and list the new calendar on the left." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:127 +msgid "Edit Calendar Names and Settings" +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:129 +#: ../../en_US/_plugins/calendar/overview.rst:137 +msgid "Select the calendar to edit by clicking it in the list." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:130 +msgid "" +"Click the gear icon in the calendars list footer and select *Edit* from the " +"options menu." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:131 +msgid "Adjust name, color or reminders settings in the edit dialog." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:132 +msgid "Click *Save* to finally update the calendar." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:135 +msgid "Remove entire Calendars" +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:138 +msgid "" +"Click the gear icon in the calendars list footer and select *Remove* from " +"the options menu." +msgstr "" + +#: ../../en_US/_plugins/calendar/overview.rst:139 +msgid "" +"After a confirmation dialog, the selected calendar with all its events will " +"be deleted. Caution: This action cannot be undone!" +msgstr "" diff --git a/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/settings.po b/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/settings.po new file mode 100644 index 00000000..25e737cf --- /dev/null +++ b/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/settings.po @@ -0,0 +1,178 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2014-11-27 23:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Polish (http://www.transifex.com/kolab/kolab-documentation/language/pl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pl\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" + +#: ../../en_US/_plugins/calendar/settings.rst:8 +msgid "Calendar Preferences" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:10 +msgid "" +"The settings for the calendar module are listed in *Settings > Preferences* " +"and are grouped by the following sections:" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:14 +msgid "Main Options" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:17 +msgid "**Default view**" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:17 +msgid "" +"Lets you select the :ref:`calendar-view` which is visible by default when " +"opening the calendar." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:21 +msgid "**Time slots per hour**" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:20 +msgid "" +"How one hour in day and week view is divided vertically. If for example set " +"to 2, you will see events displayed in 30 minute blocks." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:24 +msgid "**First weekday**" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:24 +msgid "Which weekday to begin the week view with." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:28 +msgid "**First hour to show**" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:27 +msgid "" +"When opening the day or week view, the listing of events starts at this " +"time. Of course all hours of a day are visible by scrolling further up." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:33 +msgid "**Working hours**" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:33 +msgid "" +"This time range will be used in the :ref:`availability finder ` when automatically selecting free slots for a meeting." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:40 +msgid "**Event coloring**" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:37 +msgid "" +"The coloring of the title of an event block (\"outline\") as well as the " +"background color of the box (\"content\") in day and week views is " +"influenced by the color of the calendar an event belongs to and/or the color" +" of the category it is assigned to. This setting lets you control which " +"source for coloring to use or if you even want a combined coloring that " +"reflects both, the assignment of calendars and categories." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:43 +msgid "**Default reminder setting**" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:43 +msgid "" +"When creating new events, they'll have this type of reminder set by default." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:46 +msgid "**Default reminder time**" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:46 +msgid "When enabling reminders in a new event, use this preset as default." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:51 +msgid "**Create new events in**" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:49 +msgid "" +"This is the default selection for saving new events. Used in both the " +"calendar view and when accepting event invitations." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:54 +msgid "Categories" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:56 +msgid "" +"This block allows the management of categories used in your calendar and " +"assign colors to them. Use the color picker to change the color by clicking " +"on the square color box in the categories list." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:59 +msgid "" +"To add a new category, enter its unique name into the text box below the " +"listing and then click the *Add category** button to add it. Note that you " +"still need to click the *Save* button at the bottom of the preferences panel" +" in order to finally register the new categories." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:65 +msgid "Birthdays Calendar" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:67 +msgid "" +"The calendar view and also display birthdays from contacts saved in your " +"address book. This block controls how this is done." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:71 +msgid "**Display birthdays calendar**" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:71 +msgid "Enable the birthdays calendar feature with this checkbox." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:74 +msgid "**From these address books**" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:74 +msgid "" +"Choose from which address books you'd like to see birthdays in your " +"calendar." +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:80 +msgid "**Show reminders**" +msgstr "" + +#: ../../en_US/_plugins/calendar/settings.rst:77 +msgid "" +"This option controls whether and when to display reminder notifications for " +"upcoming birthdays." +msgstr "" diff --git a/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/sharing.po b/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/sharing.po new file mode 100644 index 00000000..f6391219 --- /dev/null +++ b/plugins/calendar/helpdocs/locale/pl/LC_MESSAGES/sharing.po @@ -0,0 +1,99 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2014-11-27 23:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Polish (http://www.transifex.com/kolab/kolab-documentation/language/pl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pl\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" + +#: ../../en_US/_plugins/calendar/sharing.rst:11 +msgid "Sharing Calendars" +msgstr "" + +#: ../../en_US/_plugins/calendar/sharing.rst:13 +msgid "" +"For collaboration, sharing calendars is an important feature. In the " +":ref:`overview `, we have already learned how calendars " +"others share with you appear in the calendars list. The following now " +"explains how to make personal calendars accessible to fellow users." +msgstr "" + +#: ../../en_US/_plugins/calendar/sharing.rst:19 +msgid "Share a Calendar with others" +msgstr "" + +#: ../../en_US/_plugins/calendar/sharing.rst:21 +msgid "" +"Sharing is controlled through the :ref:`Calendar Settings Dialog `. Double-click a calendar in the list on the left and then " +"select the *Sharing* tab at the top of the dialog box:" +msgstr "" + +#: ../../en_US/_plugins/calendar/sharing.rst:27 +msgid "" +"The table displays who already has permission to see and modify the selected" +" calendar. In order to share the calendar with a new user do" +msgstr "" + +#: ../../en_US/_plugins/calendar/sharing.rst:30 +msgid "Click the *Add entry* button (+) in the table footer" +msgstr "" + +#: ../../en_US/_plugins/calendar/sharing.rst:31 +msgid "" +"Enter the username or choose one from the autocompletion menu that appears " +"when you start typing. Instead of a specific user, permissons can be granted" +" for all users or guests." +msgstr "" + +#: ../../en_US/_plugins/calendar/sharing.rst:33 +msgid "Select the access rights you want to grant for the user" +msgstr "" + +#: ../../en_US/_plugins/calendar/sharing.rst:34 +msgid "Click *Save* to add the permission" +msgstr "" + +#: ../../en_US/_plugins/calendar/sharing.rst:36 +msgid "" +"Double-click an entry to edit the permissions for a particular user or " +"group." +msgstr "" + +#: ../../en_US/_plugins/calendar/sharing.rst:38 +msgid "" +"For removing existing permissions, select the according entry in the list " +"and then choose *Delete* from the menu behind the gear icon in the footer of" +" the list." +msgstr "" + +#: ../../en_US/_plugins/calendar/sharing.rst:43 +msgid "Subscribe to Shared Calendars" +msgstr "" + +#: ../../en_US/_plugins/calendar/sharing.rst:45 +msgid "" +"Calendars shared by others are not showing up right away in the list within " +"the calendar view. Switch to :ref:`Settings > Folders ` to" +" see all resources you can access. There's a shortcut to this: click *Manage" +" folders* in the options menu behind the gear icon located the footer of the" +" calendars list." +msgstr "" + +#: ../../en_US/_plugins/calendar/sharing.rst:50 +msgid "" +"In order to make a shared calendar appear in the calendars list, locate it " +"in the folder manager and check the *Subscribed* mark in the list. Only " +"subscribed calendars are visible in the calendar view." +msgstr "" diff --git a/plugins/kolab_addressbook/helpdocs/locale/de/LC_MESSAGES/addressbook.po b/plugins/kolab_addressbook/helpdocs/locale/de/LC_MESSAGES/addressbook.po new file mode 100644 index 00000000..82aa3a21 --- /dev/null +++ b/plugins/kolab_addressbook/helpdocs/locale/de/LC_MESSAGES/addressbook.po @@ -0,0 +1,81 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +# Ettore Atalan , 2014 +# Mads , 2016 +# Max Hellwig , 2016 +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2017-09-23 20:32+0000\n" +"Last-Translator: Mads \n" +"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:9 +msgid "Sharing Address Books" +msgstr "Adressbücher teilen" + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:11 +msgid "" +"Just like calendars or regular email folders, personal address books can " +"also be shared with other users in your workgroup." +msgstr "Persönliche Adressbücher können genauso wie Kalender oder normale E-Mail-Ordner mit anderen Nutzern Ihrer Arbeitsgruppe geteilt werden. " + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:16 +msgid "Share Contacts with others" +msgstr "Kontakte mit Anderen teilen" + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:22 +msgid "" +"Settings for sharing is controlled through the address book properties " +"accessible through the *More actions* menu behind the gear icon the footer " +"in the :ref:`addressbook-groups` list." +msgstr "Die Einstellungen zum Teilen werden über die Eigenschaften des Adressbuchs gemacht, die durch das *Weitere Tätigkeiten*-Menü hinter dem Zahnradicon in der Fußzeile der :ref: `Adressbuchgruppen `-Liste zu erreichen sind. " + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:25 +msgid "Select the address book you want to share." +msgstr "Wählen Sie das Adressbuch aus, dass Sie teilen möchten." + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:26 +msgid "Choose *Edit address book* from the actions menu." +msgstr "Wählen Sie *Adressbuch bearbeiten* aus dem Tätigkeitenmenü. " + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:27 +msgid "Switch to the *Sharing* tab in the properties form on the right." +msgstr "Wechseln Sie auf den *Teilen*-Reiter in der Eigenschaftenmaske rechts. " + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:29 +msgid "" +"The table displays who already has permission to see and modify the selected" +" address book. Here you can manage permissions the same way as :ref:`Sharing" +" a Folder `." +msgstr "Die Tabelle zeigt an, wer schon die Erlaubnis hat, das ausgewählte Adressbuch zu sehen und verändern. Freigaben können hier auf die selbe Weise, wie :ref: `Ordner teilen ` verwaltet werden. " + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:34 +msgid "Subscribe to Shared Address Books" +msgstr "Geteilte Adressbücher abonnieren" + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:36 +msgid "" +"Address books shared by others are not showing up right away in the " +"directories list of the web client. Switch to :ref:`Settings > Folders " +"` to see all resources you can access. There's a shortcut " +"to this: click *Manage folders* in the actions menu behind the gear icon " +"located the footer of the directory list." +msgstr "Adressbücher, die von anderen geteilt wurden, werden nicht sofort in der Verzeichnisliste des Webclients angezeigt. Wechseln Sie zu :ref: `Einstellungen > Ordner `, um alle Hilfsmittel, auf die Sie Zugriff haben, zu sehen. Es gibt einen schnelleren Weg dorthin: Klicken Sie auf *Ordner verwalten* im Tätigkeitenmenü hinter dem Zahnradicon in der Fußzeile der Verzeichnisliste. " + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:41 +msgid "" +"In order to make a shared address book appear in the address book view, " +"locate it in the folder manager and check the *Subscribed* mark in the list." +" Only subscribed directories are visible in the address book view." +msgstr "Um ein geteiltes Adressbuch in der Adressbuchansicht anzuzeigen, wählen Sie es in der Ordnerverwaltung aus und setzen Sie bei *Abonniert* ein Häkchen in der Liste. Nur abonnierte Verzeichnisse sind in der Adressbuchansicht sichtbar. " diff --git a/plugins/kolab_addressbook/helpdocs/locale/pl/LC_MESSAGES/addressbook.po b/plugins/kolab_addressbook/helpdocs/locale/pl/LC_MESSAGES/addressbook.po new file mode 100644 index 00000000..08b737a6 --- /dev/null +++ b/plugins/kolab_addressbook/helpdocs/locale/pl/LC_MESSAGES/addressbook.po @@ -0,0 +1,78 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2014-11-27 23:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Polish (http://www.transifex.com/kolab/kolab-documentation/language/pl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pl\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:9 +msgid "Sharing Address Books" +msgstr "" + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:11 +msgid "" +"Just like calendars or regular email folders, personal address books can " +"also be shared with other users in your workgroup." +msgstr "" + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:16 +msgid "Share Contacts with others" +msgstr "" + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:22 +msgid "" +"Settings for sharing is controlled through the address book properties " +"accessible through the *More actions* menu behind the gear icon the footer " +"in the :ref:`addressbook-groups` list." +msgstr "" + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:25 +msgid "Select the address book you want to share." +msgstr "" + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:26 +msgid "Choose *Edit address book* from the actions menu." +msgstr "" + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:27 +msgid "Switch to the *Sharing* tab in the properties form on the right." +msgstr "" + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:29 +msgid "" +"The table displays who already has permission to see and modify the selected" +" address book. Here you can manage permissions the same way as :ref:`Sharing" +" a Folder `." +msgstr "" + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:34 +msgid "Subscribe to Shared Address Books" +msgstr "" + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:36 +msgid "" +"Address books shared by others are not showing up right away in the " +"directories list of the web client. Switch to :ref:`Settings > Folders " +"` to see all resources you can access. There's a shortcut " +"to this: click *Manage folders* in the actions menu behind the gear icon " +"located the footer of the directory list." +msgstr "" + +#: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:41 +msgid "" +"In order to make a shared address book appear in the address book view, " +"locate it in the folder manager and check the *Subscribed* mark in the list." +" Only subscribed directories are visible in the address book view." +msgstr "" diff --git a/plugins/tasklist/helpdocs/locale/de/LC_MESSAGES/index.po b/plugins/tasklist/helpdocs/locale/de/LC_MESSAGES/index.po new file mode 100644 index 00000000..cb5214ab --- /dev/null +++ b/plugins/tasklist/helpdocs/locale/de/LC_MESSAGES/index.po @@ -0,0 +1,29 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +# Mads , 2016 +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2017-09-23 20:32+0000\n" +"Last-Translator: Mads \n" +"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../en_US/_plugins/tasks/index.rst:9 +msgid "Tasks" +msgstr "Aufgaben" + +#: ../../en_US/_plugins/tasks/index.rst:11 +msgid "" +"The *Tasks* module helps you organize your daily jobs and ToDo's and will " +"alert you about upcoming deadlines." +msgstr "Das *Aufgaben*-Modul hilft Ihnen, Ihre täglichen Aufgaben und Pendenzen zu organisieren und meldet Ihnen bevorstehende Fristen. " diff --git a/plugins/tasklist/helpdocs/locale/de/LC_MESSAGES/manage.po b/plugins/tasklist/helpdocs/locale/de/LC_MESSAGES/manage.po new file mode 100644 index 00000000..39346955 --- /dev/null +++ b/plugins/tasklist/helpdocs/locale/de/LC_MESSAGES/manage.po @@ -0,0 +1,325 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +# Ettore Atalan , 2014 +# Gerd Seyfarth , 2015 +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2017-09-23 20:32+0000\n" +"Last-Translator: Jeroen van Meeuwen \n" +"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../en_US/_plugins/tasks/manage.rst:7 +msgid "Managing Tasks" +msgstr "Aufgaben verwalten" + +#: ../../en_US/_plugins/tasks/manage.rst:9 +msgid "" +"All the described functions to manage your tasks are accessible from the " +"main task view." +msgstr "Alle beschriebenen Funktionen zum Verwalten Ihrer Aufgaben sind in der Hauptaufgabenansicht zugänglich." + +#: ../../en_US/_plugins/tasks/manage.rst:13 +msgid "Create new Tasks" +msgstr "Neue Aufgaben erstellen" + +#: ../../en_US/_plugins/tasks/manage.rst:18 +msgid "**The New Task Dialog**" +msgstr "**Der Dialog für neue Aufgaben**" + +#: ../../en_US/_plugins/tasks/manage.rst:16 +msgid "" +"Click the *New task* button in the toolbar to get an empty dialog where you " +"enter the tasks properties like title, description, start/due dates and " +"reminder settings. Click *Save* to finally add it to the selected task list." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:27 +msgid "**Quick Entry**" +msgstr "**Schnelleintrag**" + +#: ../../en_US/_plugins/tasks/manage.rst:21 +msgid "" +"The text box in the centre of the toolbar area lets you add new tasks very " +"fast by simply entering a title and then press on the keyboard. " +"Tasks will be created in the currently selected list." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:25 +msgid "" +"Begin the quick entry with a date or time description like \"Tomorrow\" or " +"\"Monday at 16:00\" to directly assign a due date to the task." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:32 +msgid "Edit Tasks" +msgstr "Aufgaben bearbeiten" + +#: ../../en_US/_plugins/tasks/manage.rst:35 +msgid "The Edit Dialog" +msgstr "Der Bearbeitungsdialog" + +#: ../../en_US/_plugins/tasks/manage.rst:37 +msgid "" +"When clicking a task item in list a dialog showing its details is displayed." +" Clicking the Edit button in that dialog opens the form to edit all " +"properties of the selected task." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:40 +msgid "" +"The edit form is divided into different section which can be switched using " +"the tabs on top of the dialog:" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:42 +msgid "**Summary**" +msgstr "**Zusammenfassung**" + +#: ../../en_US/_plugins/tasks/manage.rst:44 +msgid "" +"This general section has text fields and selectors for various properties. " +"Here’s a description of all the possible values:" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:46 +msgid "" +"``Title``: The title of the task. This is what you will see in the list." +msgstr "``Titel``: Der Titel der Aufgabe. Das ist was Sie in der Liste sehen werden." + +#: ../../en_US/_plugins/tasks/manage.rst:47 +msgid "" +"``Description``: Any text that describes the task. Links and email addresses" +" will be become clickable." +msgstr "``Beschreibung``: Jeder Text, der die Aufgabe beschreibt. Links und E-Mail-Adressen werden anklickbar." + +#: ../../en_US/_plugins/tasks/manage.rst:48 +msgid "" +"``Tags``: A list of tags assigned to this task. Add one by typing to the " +"text box and hit ." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:49 +msgid "``Start``: The date/time, the task is supposed to be worked on." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:50 +msgid "" +"``Due``: The date/time this job is due. Define a time when setting a " +"reminder for this task." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:51 +msgid "" +"``Reminder``: This will pop up with an notification at a the specified time " +"before the task is due." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:52 +msgid "" +"``Complete``: The completeness state of a task in percent. Use the slider or" +" enter a number." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:53 +msgid "" +"``Tasklist``: The list the task is saved in. Change it to move an event from" +" one list to another." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:58 +msgid "**Attachments**" +msgstr "**Anhänge**" + +#: ../../en_US/_plugins/tasks/manage.rst:60 +msgid "" +"Append files and documents related to this task directly as attachments. " +"Switch to the Attachments tab to upload files to the current task or to " +"remove them again. Adding files works pretty much the same as " +":ref:`attaching them to email messages `: first " +"select a file from your local disk and click *Upload* in order to attach it." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:65 +msgid "" +"Don't forget to finally save the changes by clicking *Save* in the edit " +"dialog. Switching back and forth the tabs will not yet save the data." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:72 +msgid "Assign Tags" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:74 +msgid "" +"Tags help you organize your tasks in the list view. Open the :ref:`Edit " +"Dialog ` and enter tags into the according text box:" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:79 +msgid "" +"Append a tag by hitting and continue typing to add more. While " +"typing, a suggestion of already used tags will be shown. Use the arrow keys " +"on the keyboard to select one and press to select." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:82 +msgid "Remove tags with a click on the *Remove* icon." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:84 +msgid "**Drag & Drop Tags**" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:86 +msgid "" +"Existing tags listed in the tags box on the left can also be assigned to " +"tasks directly in the list view by simply dragging the tag from the box and " +"drop it on a task bar." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:93 +msgid "Set Due Dates" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:95 +msgid "" +"Assign due dates to your tasks to not miss your deadlines and to enable " +"reminder notifications for them. The due dates with time can be entered in " +"the :ref:`Edit Dialog `. When entering the input field, " +"a small calendar widget will help you to quickly select a date." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:99 +msgid "" +"Due dates can also be entered or changed directly in the list view without " +"going to the edit dialog. Click the due date or the \"no date\" area on the " +"right end of a task bar and select a date from the calendar widget. The " +"change will be saved immediately." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:107 +msgid "Mark Tasks as Complete" +msgstr "Aufgaben als abgeschlossen markieren" + +#: ../../en_US/_plugins/tasks/manage.rst:109 +msgid "" +"In the :ref:`tasklist-edit-task` section we learned how to set a percentage " +"value for a task's completeness. Until a task isn't fully completed, the " +"percentage is displayed as a think horizontal line in the list view." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:113 +msgid "" +"In order to mark a task as complete, simply click the checkbox in the list " +"view. The task is now grayed out and moved to the bottom of the list. After " +"some time or when refreshing the list, completed tasks will be removed from " +"the view. You can still find them with the *Complete* quick filter. Uncheck " +"the box to bring it back to the normal list." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:120 +msgid "Organize Tasks in Groups" +msgstr "Aufgaben in Gruppen organisieren" + +#: ../../en_US/_plugins/tasks/manage.rst:122 +msgid "" +"For bigger jobs or entire projects, tasks can be divided into subtasks and " +"organized hierarchically to visualize dependencies." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:126 +msgid "Create a Subtask" +msgstr "Teilaufgabe erstellen" + +#: ../../en_US/_plugins/tasks/manage.rst:132 +#: ../../en_US/_plugins/tasks/manage.rst:172 +msgid "" +"Open the options menu of a task from the arrow icon on the far right of the " +"task bar." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:133 +msgid "Select *Add subtask*" +msgstr "*Teilaufgabe hinzufügen* auswählen" + +#: ../../en_US/_plugins/tasks/manage.rst:134 +msgid "" +"Enter the subtask properties in the :ref:`Edit Dialog `" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:135 +msgid "Press *Save* to insert it" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:141 +msgid "Re-organize Groups" +msgstr "Gruppen umorganisieren" + +#: ../../en_US/_plugins/tasks/manage.rst:143 +msgid "" +"The hierarchical nesting of tasks and subtasks can be changed at any time. " +"Simple grab a task with the mouse and drop onto another one to make it a " +"subtask. This works for entire subtrees equally well. While dragging, a " +"possible drop target is highlighted when moving over it." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:147 +msgid "" +"Drop a task onto the small bar on top of the tasks list to make it a main " +"task again." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:149 +msgid "" +"If you organize your tasks in different lists, dropping a task onto a task " +"list in the box on the left moves it (and all child tasks) to that " +"particular list." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:157 +msgid "Get Notifications" +msgstr "Benachrichtigungen holen" + +#: ../../en_US/_plugins/tasks/manage.rst:159 +msgid "" +"While logged in to the webmail, reminders about soon-to-be due tasks will be" +" displayed with pop-up boxes at the specified time before the task is due. " +"You can specify if you want to see reminders for every task list " +"individually. Enable or disable reminders in :ref:`Task List Settings " +"` from the :ref:`tasklist-lists`." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:163 +msgid "" +"Read how to :ref:`Dismiss or Snooze Reminders ` in " +"the calendar section." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:167 +msgid "Delete Tasks" +msgstr "Aufgaben löschen" + +#: ../../en_US/_plugins/tasks/manage.rst:169 +msgid "" +"Usually finished tasks are marked as complete. But there are still " +"situations where you might want to actually delete a task." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:173 +msgid "Select *Delete*." +msgstr "*Löschen* auswählen." + +#: ../../en_US/_plugins/tasks/manage.rst:174 +msgid "Click *Delete* again in the confirmation dialog." +msgstr "Klicken Sie im Bestätigungsdialog erneut auf *Löschen*." diff --git a/plugins/tasklist/helpdocs/locale/de/LC_MESSAGES/overview.po b/plugins/tasklist/helpdocs/locale/de/LC_MESSAGES/overview.po new file mode 100644 index 00000000..4bec001e --- /dev/null +++ b/plugins/tasklist/helpdocs/locale/de/LC_MESSAGES/overview.po @@ -0,0 +1,199 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +# Ettore Atalan , 2014 +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2017-09-23 20:32+0000\n" +"Last-Translator: Jeroen van Meeuwen \n" +"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../en_US/_plugins/tasks/overview.rst:6 +msgid "Overview" +msgstr "Übersicht" + +#: ../../en_US/_plugins/tasks/overview.rst:8 +msgid "" +"The content area of the tasks screen is divided into three areas: the " +":ref:`Tasks ` itself, the :ref:`Tags ` and " +"the :ref:`Tasklist Selector `." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:16 +msgid "The Tasks List" +msgstr "Die Aufgabenliste" + +#: ../../en_US/_plugins/tasks/overview.rst:18 +msgid "" +"The main content are lists the task items that match the current selection " +"of active lists, filters and tags. The listed tasks are sorted by due date " +"(ascending) and completed ones move to the bottom." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:25 +msgid "" +"Tasks can be organized hierarchically and the list appears like a tree " +"structure. A small arrow icon on the left side of a task bar indicates " +"subordinated tasks and expands or collapses the tree upon click." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:29 +msgid "" +"Some basic editing like flagging, assigning a due date as well as completing" +" tasks can directly be done in the list by clicking the checkbox, the flag " +"icon or the date selector." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:32 +msgid "" +"A single click anywhere else on a task bar displays all details in a dialog " +"box. Hit on the keyboard or click the close icon to hide it again." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:35 +msgid "Double-clicks open the clicked task item for full detail editing." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:39 +msgid "Control the List" +msgstr "Listensteuerung" + +#: ../../en_US/_plugins/tasks/overview.rst:42 +msgid "Quick Filters" +msgstr "Schnellfilter" + +#: ../../en_US/_plugins/tasks/overview.rst:44 +msgid "" +"The selection your tasks displayed on the screen can be refined in various " +"ways. Use the quick filters above the list to reduce the listed tasks " +"according to their status or due date." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:50 +msgid "Tags" +msgstr "Schlagworte" + +#: ../../en_US/_plugins/tasks/overview.rst:52 +msgid "" +"The tags list on the left is another way to display a selection of tasks. " +"Click a tag to only display tasks with this tag assigned. Click it again to " +"show all. Hold down the key on the the keyboard to select mutliple " +"tags and further reduce the selection." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:57 +#: ../../en_US/_plugins/tasks/overview.rst:83 +msgid "Task Lists" +msgstr "Aufgabenliste" + +#: ../../en_US/_plugins/tasks/overview.rst:59 +msgid "" +"The checkboxes in the :ref:`tasklist-lists` box control whether tasks from " +"the according list are currently displayed. Use the *Quick View* icon " +"|quickview| in the list to quickly reduce the view to tasks from a single " +"list. This can also be used when the according list isn't activated. Click " +"it again to turn off quick view mode and return to regular display of active" +" lists." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:68 +msgid "Searching Tasks" +msgstr "Aufgabensuche" + +#: ../../en_US/_plugins/tasks/overview.rst:70 +msgid "" +"The search box above the calendar view lets you quickly get a list of events" +" matching the entered keyword in either the title or the description text. " +"Enter the search term into the box and press on your keyboard to " +"start the search." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:73 +msgid "" +"After searching, you can still use the filters and tags as explained above " +"to hide some results." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:75 +msgid "" +"Reset the search by clicking the *Reset search* icon on the right border of " +"the search box." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:85 +msgid "" +"Organize your tasks in various lists. All of your personal task lists as " +"well as those shared by others are listed in the box in the lower left area " +"of the screen." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:88 +msgid "" +"You can create any number of lists to store and manage all your tasks and " +"name them individually." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:92 +msgid "Create a Task List" +msgstr "Aufgabenliste erstellten" + +#: ../../en_US/_plugins/tasks/overview.rst:94 +msgid "Click the + icon in the tasklists box footer." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:95 +msgid "In the dialog, give the new list a unique name." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:96 +msgid "Click *Save* to create it." +msgstr "Klicken Sie auf *Speichern* zum Erstellen." + +#: ../../en_US/_plugins/tasks/overview.rst:101 +msgid "Edit List Names and Settings" +msgstr "Listennamen und Einstellungen bearbeiten" + +#: ../../en_US/_plugins/tasks/overview.rst:103 +#: ../../en_US/_plugins/tasks/overview.rst:111 +msgid "Select the task list to edit by clicking the name in the box." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:104 +msgid "" +"Click the gear icon in the box footer and select *Edit* from the options " +"menu." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:105 +msgid "Adjust name or reminders settings in the edit dialog." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:106 +msgid "Click *Save* to finally update the list." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:109 +msgid "Remove entire Task Lists" +msgstr "Gesamte Aufgabenliste entfernen" + +#: ../../en_US/_plugins/tasks/overview.rst:112 +msgid "" +"Click the gear icon in the box footer and select *Remove* from the options " +"menu." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:113 +msgid "" +"After a confirmation dialog, the selected list with all its tasks will be " +"deleted. Caution: This action cannot be undone!" +msgstr "" diff --git a/plugins/tasklist/helpdocs/locale/pl/LC_MESSAGES/index.po b/plugins/tasklist/helpdocs/locale/pl/LC_MESSAGES/index.po new file mode 100644 index 00000000..ac2c05cc --- /dev/null +++ b/plugins/tasklist/helpdocs/locale/pl/LC_MESSAGES/index.po @@ -0,0 +1,28 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2014-11-27 23:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Polish (http://www.transifex.com/kolab/kolab-documentation/language/pl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pl\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" + +#: ../../en_US/_plugins/tasks/index.rst:9 +msgid "Tasks" +msgstr "" + +#: ../../en_US/_plugins/tasks/index.rst:11 +msgid "" +"The *Tasks* module helps you organize your daily jobs and ToDo's and will " +"alert you about upcoming deadlines." +msgstr "" diff --git a/plugins/tasklist/helpdocs/locale/pl/LC_MESSAGES/manage.po b/plugins/tasklist/helpdocs/locale/pl/LC_MESSAGES/manage.po new file mode 100644 index 00000000..c6e08fc0 --- /dev/null +++ b/plugins/tasklist/helpdocs/locale/pl/LC_MESSAGES/manage.po @@ -0,0 +1,323 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2014-11-27 23:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Polish (http://www.transifex.com/kolab/kolab-documentation/language/pl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pl\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" + +#: ../../en_US/_plugins/tasks/manage.rst:7 +msgid "Managing Tasks" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:9 +msgid "" +"All the described functions to manage your tasks are accessible from the " +"main task view." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:13 +msgid "Create new Tasks" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:18 +msgid "**The New Task Dialog**" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:16 +msgid "" +"Click the *New task* button in the toolbar to get an empty dialog where you " +"enter the tasks properties like title, description, start/due dates and " +"reminder settings. Click *Save* to finally add it to the selected task list." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:27 +msgid "**Quick Entry**" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:21 +msgid "" +"The text box in the centre of the toolbar area lets you add new tasks very " +"fast by simply entering a title and then press on the keyboard. " +"Tasks will be created in the currently selected list." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:25 +msgid "" +"Begin the quick entry with a date or time description like \"Tomorrow\" or " +"\"Monday at 16:00\" to directly assign a due date to the task." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:32 +msgid "Edit Tasks" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:35 +msgid "The Edit Dialog" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:37 +msgid "" +"When clicking a task item in list a dialog showing its details is displayed." +" Clicking the Edit button in that dialog opens the form to edit all " +"properties of the selected task." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:40 +msgid "" +"The edit form is divided into different section which can be switched using " +"the tabs on top of the dialog:" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:42 +msgid "**Summary**" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:44 +msgid "" +"This general section has text fields and selectors for various properties. " +"Here’s a description of all the possible values:" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:46 +msgid "" +"``Title``: The title of the task. This is what you will see in the list." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:47 +msgid "" +"``Description``: Any text that describes the task. Links and email addresses" +" will be become clickable." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:48 +msgid "" +"``Tags``: A list of tags assigned to this task. Add one by typing to the " +"text box and hit ." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:49 +msgid "``Start``: The date/time, the task is supposed to be worked on." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:50 +msgid "" +"``Due``: The date/time this job is due. Define a time when setting a " +"reminder for this task." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:51 +msgid "" +"``Reminder``: This will pop up with an notification at a the specified time " +"before the task is due." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:52 +msgid "" +"``Complete``: The completeness state of a task in percent. Use the slider or" +" enter a number." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:53 +msgid "" +"``Tasklist``: The list the task is saved in. Change it to move an event from" +" one list to another." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:58 +msgid "**Attachments**" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:60 +msgid "" +"Append files and documents related to this task directly as attachments. " +"Switch to the Attachments tab to upload files to the current task or to " +"remove them again. Adding files works pretty much the same as " +":ref:`attaching them to email messages `: first " +"select a file from your local disk and click *Upload* in order to attach it." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:65 +msgid "" +"Don't forget to finally save the changes by clicking *Save* in the edit " +"dialog. Switching back and forth the tabs will not yet save the data." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:72 +msgid "Assign Tags" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:74 +msgid "" +"Tags help you organize your tasks in the list view. Open the :ref:`Edit " +"Dialog ` and enter tags into the according text box:" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:79 +msgid "" +"Append a tag by hitting and continue typing to add more. While " +"typing, a suggestion of already used tags will be shown. Use the arrow keys " +"on the keyboard to select one and press to select." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:82 +msgid "Remove tags with a click on the *Remove* icon." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:84 +msgid "**Drag & Drop Tags**" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:86 +msgid "" +"Existing tags listed in the tags box on the left can also be assigned to " +"tasks directly in the list view by simply dragging the tag from the box and " +"drop it on a task bar." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:93 +msgid "Set Due Dates" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:95 +msgid "" +"Assign due dates to your tasks to not miss your deadlines and to enable " +"reminder notifications for them. The due dates with time can be entered in " +"the :ref:`Edit Dialog `. When entering the input field, " +"a small calendar widget will help you to quickly select a date." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:99 +msgid "" +"Due dates can also be entered or changed directly in the list view without " +"going to the edit dialog. Click the due date or the \"no date\" area on the " +"right end of a task bar and select a date from the calendar widget. The " +"change will be saved immediately." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:107 +msgid "Mark Tasks as Complete" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:109 +msgid "" +"In the :ref:`tasklist-edit-task` section we learned how to set a percentage " +"value for a task's completeness. Until a task isn't fully completed, the " +"percentage is displayed as a think horizontal line in the list view." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:113 +msgid "" +"In order to mark a task as complete, simply click the checkbox in the list " +"view. The task is now grayed out and moved to the bottom of the list. After " +"some time or when refreshing the list, completed tasks will be removed from " +"the view. You can still find them with the *Complete* quick filter. Uncheck " +"the box to bring it back to the normal list." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:120 +msgid "Organize Tasks in Groups" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:122 +msgid "" +"For bigger jobs or entire projects, tasks can be divided into subtasks and " +"organized hierarchically to visualize dependencies." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:126 +msgid "Create a Subtask" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:132 +#: ../../en_US/_plugins/tasks/manage.rst:172 +msgid "" +"Open the options menu of a task from the arrow icon on the far right of the " +"task bar." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:133 +msgid "Select *Add subtask*" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:134 +msgid "" +"Enter the subtask properties in the :ref:`Edit Dialog `" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:135 +msgid "Press *Save* to insert it" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:141 +msgid "Re-organize Groups" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:143 +msgid "" +"The hierarchical nesting of tasks and subtasks can be changed at any time. " +"Simple grab a task with the mouse and drop onto another one to make it a " +"subtask. This works for entire subtrees equally well. While dragging, a " +"possible drop target is highlighted when moving over it." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:147 +msgid "" +"Drop a task onto the small bar on top of the tasks list to make it a main " +"task again." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:149 +msgid "" +"If you organize your tasks in different lists, dropping a task onto a task " +"list in the box on the left moves it (and all child tasks) to that " +"particular list." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:157 +msgid "Get Notifications" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:159 +msgid "" +"While logged in to the webmail, reminders about soon-to-be due tasks will be" +" displayed with pop-up boxes at the specified time before the task is due. " +"You can specify if you want to see reminders for every task list " +"individually. Enable or disable reminders in :ref:`Task List Settings " +"` from the :ref:`tasklist-lists`." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:163 +msgid "" +"Read how to :ref:`Dismiss or Snooze Reminders ` in " +"the calendar section." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:167 +msgid "Delete Tasks" +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:169 +msgid "" +"Usually finished tasks are marked as complete. But there are still " +"situations where you might want to actually delete a task." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:173 +msgid "Select *Delete*." +msgstr "" + +#: ../../en_US/_plugins/tasks/manage.rst:174 +msgid "Click *Delete* again in the confirmation dialog." +msgstr "" diff --git a/plugins/tasklist/helpdocs/locale/pl/LC_MESSAGES/overview.po b/plugins/tasklist/helpdocs/locale/pl/LC_MESSAGES/overview.po new file mode 100644 index 00000000..2b0b8524 --- /dev/null +++ b/plugins/tasklist/helpdocs/locale/pl/LC_MESSAGES/overview.po @@ -0,0 +1,198 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2014, roundcube.net +# This file is distributed under the same license as the Roundcube Webmail Help package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Kolab Documentation\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-26 23:28+0100\n" +"PO-Revision-Date: 2014-11-27 23:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Polish (http://www.transifex.com/kolab/kolab-documentation/language/pl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pl\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" + +#: ../../en_US/_plugins/tasks/overview.rst:6 +msgid "Overview" +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:8 +msgid "" +"The content area of the tasks screen is divided into three areas: the " +":ref:`Tasks ` itself, the :ref:`Tags ` and " +"the :ref:`Tasklist Selector `." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:16 +msgid "The Tasks List" +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:18 +msgid "" +"The main content are lists the task items that match the current selection " +"of active lists, filters and tags. The listed tasks are sorted by due date " +"(ascending) and completed ones move to the bottom." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:25 +msgid "" +"Tasks can be organized hierarchically and the list appears like a tree " +"structure. A small arrow icon on the left side of a task bar indicates " +"subordinated tasks and expands or collapses the tree upon click." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:29 +msgid "" +"Some basic editing like flagging, assigning a due date as well as completing" +" tasks can directly be done in the list by clicking the checkbox, the flag " +"icon or the date selector." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:32 +msgid "" +"A single click anywhere else on a task bar displays all details in a dialog " +"box. Hit on the keyboard or click the close icon to hide it again." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:35 +msgid "Double-clicks open the clicked task item for full detail editing." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:39 +msgid "Control the List" +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:42 +msgid "Quick Filters" +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:44 +msgid "" +"The selection your tasks displayed on the screen can be refined in various " +"ways. Use the quick filters above the list to reduce the listed tasks " +"according to their status or due date." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:50 +msgid "Tags" +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:52 +msgid "" +"The tags list on the left is another way to display a selection of tasks. " +"Click a tag to only display tasks with this tag assigned. Click it again to " +"show all. Hold down the key on the the keyboard to select mutliple " +"tags and further reduce the selection." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:57 +#: ../../en_US/_plugins/tasks/overview.rst:83 +msgid "Task Lists" +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:59 +msgid "" +"The checkboxes in the :ref:`tasklist-lists` box control whether tasks from " +"the according list are currently displayed. Use the *Quick View* icon " +"|quickview| in the list to quickly reduce the view to tasks from a single " +"list. This can also be used when the according list isn't activated. Click " +"it again to turn off quick view mode and return to regular display of active" +" lists." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:68 +msgid "Searching Tasks" +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:70 +msgid "" +"The search box above the calendar view lets you quickly get a list of events" +" matching the entered keyword in either the title or the description text. " +"Enter the search term into the box and press on your keyboard to " +"start the search." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:73 +msgid "" +"After searching, you can still use the filters and tags as explained above " +"to hide some results." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:75 +msgid "" +"Reset the search by clicking the *Reset search* icon on the right border of " +"the search box." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:85 +msgid "" +"Organize your tasks in various lists. All of your personal task lists as " +"well as those shared by others are listed in the box in the lower left area " +"of the screen." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:88 +msgid "" +"You can create any number of lists to store and manage all your tasks and " +"name them individually." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:92 +msgid "Create a Task List" +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:94 +msgid "Click the + icon in the tasklists box footer." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:95 +msgid "In the dialog, give the new list a unique name." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:96 +msgid "Click *Save* to create it." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:101 +msgid "Edit List Names and Settings" +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:103 +#: ../../en_US/_plugins/tasks/overview.rst:111 +msgid "Select the task list to edit by clicking the name in the box." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:104 +msgid "" +"Click the gear icon in the box footer and select *Edit* from the options " +"menu." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:105 +msgid "Adjust name or reminders settings in the edit dialog." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:106 +msgid "Click *Save* to finally update the list." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:109 +msgid "Remove entire Task Lists" +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:112 +msgid "" +"Click the gear icon in the box footer and select *Remove* from the options " +"menu." +msgstr "" + +#: ../../en_US/_plugins/tasks/overview.rst:113 +msgid "" +"After a confirmation dialog, the selected list with all its tasks will be " +"deleted. Caution: This action cannot be undone!" +msgstr "" From 038d6fcdafb793c8b1e3db698e58c1d433fdb9ae Mon Sep 17 00:00:00 2001 From: "Jeroen van Meeuwen (Kolab Systems)" Date: Wed, 19 Dec 2018 10:08:38 +0100 Subject: [PATCH 03/98] Update .po files --- .../locale/de_DE/LC_MESSAGES/importexport.po | 31 ++++++------ .../locale/de_DE/LC_MESSAGES/index.po | 13 +++-- .../locale/de_DE/LC_MESSAGES/invitations.po | 15 +++--- .../locale/de_DE/LC_MESSAGES/manage.po | 25 +++++----- .../locale/de_DE/LC_MESSAGES/overview.po | 41 ++++++++------- .../locale/de_DE/LC_MESSAGES/settings.po | 41 ++++++++------- .../locale/de_DE/LC_MESSAGES/sharing.po | 39 +++++++-------- .../locale/de_DE/LC_MESSAGES/addressbook.po | 33 ++++++------ .../locale/de_DE/LC_MESSAGES/index.po | 13 +++-- .../locale/de_DE/LC_MESSAGES/manage.po | 50 +++++++++---------- .../locale/de_DE/LC_MESSAGES/overview.po | 31 ++++++------ 11 files changed, 157 insertions(+), 175 deletions(-) diff --git a/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/importexport.po b/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/importexport.po index 0a6b450c..3f01ab99 100644 --- a/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/importexport.po +++ b/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/importexport.po @@ -3,26 +3,23 @@ # This file is distributed under the same license as the Roundcube Webmail Help package. # # Translators: -# Ettore Atalan , 2014 -# Gerd Seyfarth , 2015 -# Jeroen van Meeuwen , 2016 msgid "" msgstr "" "Project-Id-Version: Kolab Documentation\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-11-26 23:28+0100\n" -"PO-Revision-Date: 2017-09-23 20:32+0000\n" -"Last-Translator: Jeroen van Meeuwen \n" -"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"PO-Revision-Date: 2014-11-27 23:33+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: German (Germany) (http://www.transifex.com/kolab/kolab-documentation/language/de_DE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: de\n" +"Language: de_DE\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../../en_US/_plugins/calendar/importexport.rst:9 msgid "Import/Export" -msgstr "Importieren/Exportieren" +msgstr "" #: ../../en_US/_plugins/calendar/importexport.rst:11 msgid "" @@ -32,7 +29,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/importexport.rst:16 msgid "Importing Events" -msgstr "Termine werden importiert" +msgstr "" #: ../../en_US/_plugins/calendar/importexport.rst:18 msgid "This is how to add events from an |iCal|_ (.ics) file:" @@ -40,15 +37,15 @@ msgstr "" #: ../../en_US/_plugins/calendar/importexport.rst:20 msgid "Click the *Import* toolbar button in the calendar view." -msgstr "Klicken Sie in der Kalenderansicht auf die Werkzeugleistenschaltfläche *Import*." +msgstr "" #: ../../en_US/_plugins/calendar/importexport.rst:21 msgid "Then select the file to import from your computer's hard drive." -msgstr "Dann die Datei für den Import von Ihrer Festplatte wählen." +msgstr "" #: ../../en_US/_plugins/calendar/importexport.rst:22 msgid "Select the calendar to import the events to." -msgstr "Wählen Sie den Kalender zum Importieren der Termine aus." +msgstr "" #: ../../en_US/_plugins/calendar/importexport.rst:23 msgid "Select the threshold for old events to be imported." @@ -56,7 +53,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/importexport.rst:24 msgid "Click *Import* and wait for the upload to finish." -msgstr "Klicken Sie auf *Import* und warten Sie, bis das Hochladen abgeschlossen ist." +msgstr "" #: ../../en_US/_plugins/calendar/importexport.rst:26 msgid "" @@ -66,7 +63,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/importexport.rst:34 msgid "Exporting Events" -msgstr "Termine werden exportiert" +msgstr "" #: ../../en_US/_plugins/calendar/importexport.rst:36 msgid "" @@ -76,11 +73,11 @@ msgstr "" #: ../../en_US/_plugins/calendar/importexport.rst:38 msgid "Click the *Export* toolbar button in the calendar view." -msgstr "Klicken Sie in der Kalenderansicht auf die Werkzeugleistenschaltfläche *Export*." +msgstr "" #: ../../en_US/_plugins/calendar/importexport.rst:39 msgid "Select the calendar where events should be exported from." -msgstr "Kalender wählen dessen Termine exportiert werden sollen." +msgstr "" #: ../../en_US/_plugins/calendar/importexport.rst:40 msgid "" @@ -90,7 +87,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/importexport.rst:41 msgid "Click the *Export* button to start the export." -msgstr "Klicken Sie auf die Schaltfläche *Export*, um den Export zu starten." +msgstr "" #: ../../en_US/_plugins/calendar/importexport.rst:42 msgid "" diff --git a/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/index.po b/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/index.po index 4462b632..43682ef4 100644 --- a/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/index.po +++ b/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/index.po @@ -3,27 +3,26 @@ # This file is distributed under the same license as the Roundcube Webmail Help package. # # Translators: -# Ettore Atalan , 2014 msgid "" msgstr "" "Project-Id-Version: Kolab Documentation\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-11-26 23:28+0100\n" -"PO-Revision-Date: 2017-09-23 20:32+0000\n" -"Last-Translator: Jeroen van Meeuwen \n" -"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"PO-Revision-Date: 2014-11-27 23:33+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: German (Germany) (http://www.transifex.com/kolab/kolab-documentation/language/de_DE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: de\n" +"Language: de_DE\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../../en_US/_plugins/calendar/index.rst:9 msgid "Calendar" -msgstr "Kalender" +msgstr "" #: ../../en_US/_plugins/calendar/index.rst:11 msgid "" "The *Calendar* gives you access to your personal and shared calendar and " "scheduling functions." -msgstr "Der *Kalender* ermöglicht Ihnen den Zugriff auf Ihren persönlichen und den gemeinsamen Kalender sowie auf Planungsfunktionen." +msgstr "" diff --git a/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/invitations.po b/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/invitations.po index 2bc6d6ef..ad5ac465 100644 --- a/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/invitations.po +++ b/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/invitations.po @@ -3,19 +3,18 @@ # This file is distributed under the same license as the Roundcube Webmail Help package. # # Translators: -# Ettore Atalan , 2014 msgid "" msgstr "" "Project-Id-Version: Kolab Documentation\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-11-26 23:28+0100\n" -"PO-Revision-Date: 2017-09-23 20:32+0000\n" -"Last-Translator: Jeroen van Meeuwen \n" -"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"PO-Revision-Date: 2014-11-27 23:33+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: German (Germany) (http://www.transifex.com/kolab/kolab-documentation/language/de_DE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: de\n" +"Language: de_DE\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../../en_US/_plugins/calendar/invitations.rst:8 @@ -32,7 +31,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/invitations.rst:17 msgid "Receive Event Invitations" -msgstr "Termineinladungen erhalten" +msgstr "" #: ../../en_US/_plugins/calendar/invitations.rst:19 msgid "" @@ -42,7 +41,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/invitations.rst:25 msgid "Accept/Decline Invitations" -msgstr "Einladungen annehmen/ablehnen" +msgstr "" #: ../../en_US/_plugins/calendar/invitations.rst:27 msgid "" @@ -75,7 +74,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/invitations.rst:43 msgid "Process Invitation Replies" -msgstr "Einladungsantworten abarbeiten" +msgstr "" #: ../../en_US/_plugins/calendar/invitations.rst:45 msgid "" diff --git a/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/manage.po b/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/manage.po index ffdec701..dfea103d 100644 --- a/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/manage.po +++ b/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/manage.po @@ -3,19 +3,18 @@ # This file is distributed under the same license as the Roundcube Webmail Help package. # # Translators: -# Ettore Atalan , 2014 msgid "" msgstr "" "Project-Id-Version: Kolab Documentation\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-11-26 23:28+0100\n" -"PO-Revision-Date: 2017-09-23 20:32+0000\n" -"Last-Translator: Jeroen van Meeuwen \n" -"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"PO-Revision-Date: 2014-11-27 23:33+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: German (Germany) (http://www.transifex.com/kolab/kolab-documentation/language/de_DE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: de\n" +"Language: de_DE\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../../en_US/_plugins/calendar/manage.rst:7 @@ -30,7 +29,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/manage.rst:13 msgid "Add Events to a Calendar" -msgstr "Termine zum Kalender hinzufügen" +msgstr "" #: ../../en_US/_plugins/calendar/manage.rst:18 msgid "**Via toolbar**" @@ -65,11 +64,11 @@ msgstr "" #: ../../en_US/_plugins/calendar/manage.rst:33 msgid "Edit and Reschedule Events" -msgstr "Termine bearbeiten und verlegen" +msgstr "" #: ../../en_US/_plugins/calendar/manage.rst:36 msgid "The Event Dialog" -msgstr "Der Termindialog" +msgstr "" #: ../../en_US/_plugins/calendar/manage.rst:38 msgid "" @@ -86,7 +85,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/manage.rst:44 msgid "**Summary**" -msgstr "**Zusammenfassung**" +msgstr "" #: ../../en_US/_plugins/calendar/manage.rst:46 msgid "" @@ -188,7 +187,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/manage.rst:73 msgid "**Participants**" -msgstr "**Teilnehmer**" +msgstr "" #: ../../en_US/_plugins/calendar/manage.rst:75 msgid "" @@ -200,7 +199,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/manage.rst:79 msgid "**Attachments**" -msgstr "**Anhänge**" +msgstr "" #: ../../en_US/_plugins/calendar/manage.rst:81 msgid "" @@ -239,7 +238,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/manage.rst:111 msgid "Get Notifications" -msgstr "Benachrichtigungen holen" +msgstr "" #: ../../en_US/_plugins/calendar/manage.rst:117 msgid "" @@ -334,7 +333,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/manage.rst:170 msgid "Receive Event Invitations" -msgstr "Termineinladungen erhalten" +msgstr "" #: ../../en_US/_plugins/calendar/manage.rst:172 msgid "" diff --git a/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/overview.po b/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/overview.po index 5e6f0dc6..4cdf5ad2 100644 --- a/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/overview.po +++ b/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/overview.po @@ -3,24 +3,23 @@ # This file is distributed under the same license as the Roundcube Webmail Help package. # # Translators: -# Ettore Atalan , 2014 msgid "" msgstr "" "Project-Id-Version: Kolab Documentation\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-11-26 23:28+0100\n" -"PO-Revision-Date: 2017-09-23 20:32+0000\n" -"Last-Translator: Jeroen van Meeuwen \n" -"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"PO-Revision-Date: 2014-11-27 23:33+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: German (Germany) (http://www.transifex.com/kolab/kolab-documentation/language/de_DE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: de\n" +"Language: de_DE\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../../en_US/_plugins/calendar/overview.rst:6 msgid "Overview" -msgstr "Übersicht" +msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:8 msgid "" @@ -32,7 +31,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:17 msgid "Calendar View" -msgstr "Kalenderansicht" +msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:19 msgid "" @@ -44,7 +43,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:27 msgid "Change Views" -msgstr "Ansichten ändern" +msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:29 msgid "" @@ -54,7 +53,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:34 msgid "**Day**" -msgstr "**Tag**" +msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:33 msgid "" @@ -65,7 +64,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:37 msgid "**Week**" -msgstr "**Woche**" +msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:37 msgid "" @@ -75,7 +74,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:42 msgid "**Month**" -msgstr "**Monat**" +msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:40 msgid "" @@ -87,7 +86,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:47 msgid "**Agenda**" -msgstr "**Tagesordnung**" +msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:45 msgid "" @@ -106,7 +105,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:54 msgid "Go to a specific Date" -msgstr "Zu einem bestimmten Datum gehen" +msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:56 msgid "" @@ -126,7 +125,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:64 msgid "Show Event Details" -msgstr "Termindetails anzeigen" +msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:66 msgid "" @@ -136,7 +135,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:70 msgid "Searching Events" -msgstr "Terminsuche" +msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:72 msgid "" @@ -172,7 +171,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:93 msgid "Calendars List" -msgstr "Kalenderliste" +msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:95 msgid "" @@ -191,7 +190,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:106 msgid "Colorized Events" -msgstr "Eingefärbte Termine" +msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:108 msgid "" @@ -209,7 +208,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:116 msgid "Create a New Calendar" -msgstr "Einen neuen Kalender erstellen" +msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:118 msgid "Click the + icon in the calendars list footer." @@ -221,7 +220,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:120 msgid "Click *Save* to create it." -msgstr "Klicken Sie auf *Speichern* zum Erstellen." +msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:122 msgid "The calendar view will reload and list the new calendar on the left." @@ -229,7 +228,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:127 msgid "Edit Calendar Names and Settings" -msgstr "Kalendernamen und Einstellungen bearbeiten" +msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:129 #: ../../en_US/_plugins/calendar/overview.rst:137 @@ -252,7 +251,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:135 msgid "Remove entire Calendars" -msgstr "Gesamte Kalender entfernen" +msgstr "" #: ../../en_US/_plugins/calendar/overview.rst:138 msgid "" diff --git a/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/settings.po b/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/settings.po index 298df039..c7c976ea 100644 --- a/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/settings.po +++ b/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/settings.po @@ -3,24 +3,23 @@ # This file is distributed under the same license as the Roundcube Webmail Help package. # # Translators: -# Ettore Atalan , 2014 msgid "" msgstr "" "Project-Id-Version: Kolab Documentation\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-11-26 23:28+0100\n" -"PO-Revision-Date: 2017-09-23 20:32+0000\n" -"Last-Translator: Jeroen van Meeuwen \n" -"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"PO-Revision-Date: 2014-11-27 23:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: German (Germany) (http://www.transifex.com/kolab/kolab-documentation/language/de_DE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: de\n" +"Language: de_DE\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../../en_US/_plugins/calendar/settings.rst:8 msgid "Calendar Preferences" -msgstr "Kalendereinstellungen" +msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:10 msgid "" @@ -30,11 +29,11 @@ msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:14 msgid "Main Options" -msgstr "Hauptoptionen" +msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:17 msgid "**Default view**" -msgstr "**Standardansicht**" +msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:17 msgid "" @@ -44,7 +43,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:21 msgid "**Time slots per hour**" -msgstr "**Zeitfenster pro Stunde**" +msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:20 msgid "" @@ -54,7 +53,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:24 msgid "**First weekday**" -msgstr "**Erster Wochentag**" +msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:24 msgid "Which weekday to begin the week view with." @@ -62,7 +61,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:28 msgid "**First hour to show**" -msgstr "**Erste angezeigte Stunde**" +msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:27 msgid "" @@ -72,7 +71,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:33 msgid "**Working hours**" -msgstr "**Arbeitszeiten**" +msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:33 msgid "" @@ -82,7 +81,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:40 msgid "**Event coloring**" -msgstr "**Einfärbung der Termine**" +msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:37 msgid "" @@ -96,7 +95,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:43 msgid "**Default reminder setting**" -msgstr "**Standard-Erinnerungseinstellung**" +msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:43 msgid "" @@ -105,7 +104,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:46 msgid "**Default reminder time**" -msgstr "**Standard-Erinnerungszeit**" +msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:46 msgid "When enabling reminders in a new event, use this preset as default." @@ -113,7 +112,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:51 msgid "**Create new events in**" -msgstr "**Neue Termine erstellen in**" +msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:49 msgid "" @@ -123,7 +122,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:54 msgid "Categories" -msgstr "Kategorien" +msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:56 msgid "" @@ -142,7 +141,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:65 msgid "Birthdays Calendar" -msgstr "Geburtstagskalender" +msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:67 msgid "" @@ -152,7 +151,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:71 msgid "**Display birthdays calendar**" -msgstr "**Geburtstagskalender anzeigen**" +msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:71 msgid "Enable the birthdays calendar feature with this checkbox." @@ -160,7 +159,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:74 msgid "**From these address books**" -msgstr "**Von diesen Adressbüchern**" +msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:74 msgid "" @@ -170,7 +169,7 @@ msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:80 msgid "**Show reminders**" -msgstr "**Erinnerungen anzeigen**" +msgstr "" #: ../../en_US/_plugins/calendar/settings.rst:77 msgid "" diff --git a/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/sharing.po b/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/sharing.po index 43ac9df3..391fd65b 100644 --- a/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/sharing.po +++ b/plugins/calendar/helpdocs/locale/de_DE/LC_MESSAGES/sharing.po @@ -3,26 +3,23 @@ # This file is distributed under the same license as the Roundcube Webmail Help package. # # Translators: -# Ettore Atalan , 2014 -# Mads , 2016 -# Max Hellwig , 2016 msgid "" msgstr "" "Project-Id-Version: Kolab Documentation\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-11-26 23:28+0100\n" -"PO-Revision-Date: 2017-09-23 20:32+0000\n" -"Last-Translator: Max Hellwig \n" -"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"PO-Revision-Date: 2014-11-27 23:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: German (Germany) (http://www.transifex.com/kolab/kolab-documentation/language/de_DE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: de\n" +"Language: de_DE\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../../en_US/_plugins/calendar/sharing.rst:11 msgid "Sharing Calendars" -msgstr "Kalender teilen" +msgstr "" #: ../../en_US/_plugins/calendar/sharing.rst:13 msgid "" @@ -30,60 +27,60 @@ msgid "" ":ref:`overview `, we have already learned how calendars " "others share with you appear in the calendars list. The following now " "explains how to make personal calendars accessible to fellow users." -msgstr "Kalender zu teilen ist ein wichtiger Teil der Zusammenarbeit. In der :ref:`Übersicht ` haben wir schon gelernt, wie Kalender, die von anderen mit Ihnen teilen, in der Kalenderliste aussehen. Im Folgenden wird jetzt erklärt wie man persönliche Kalender für andere Benutzer zugänglich macht." +msgstr "" #: ../../en_US/_plugins/calendar/sharing.rst:19 msgid "Share a Calendar with others" -msgstr "Einen Kalender mit Anderen teilen" +msgstr "" #: ../../en_US/_plugins/calendar/sharing.rst:21 msgid "" "Sharing is controlled through the :ref:`Calendar Settings Dialog `. Double-click a calendar in the list on the left and then " "select the *Sharing* tab at the top of the dialog box:" -msgstr "Das Teilen wird über den :ref:`Kalendereinstellungen-Dialog ` gesteuert. Doppelklicken Sie einen Kalenders in der Liste links und wählen dann den *Teilen*-Reiter im oberen Teil des Dialogfensters aus:" +msgstr "" #: ../../en_US/_plugins/calendar/sharing.rst:27 msgid "" "The table displays who already has permission to see and modify the selected" " calendar. In order to share the calendar with a new user do" -msgstr "Die Tabelle zeigt an, wer schon Erlaubnis hat, den ausgewählten Kalender zu sehen und verändern. Um den Kalender mit einem neuen Benutzer zu teilen," +msgstr "" #: ../../en_US/_plugins/calendar/sharing.rst:30 msgid "Click the *Add entry* button (+) in the table footer" -msgstr "klicken Sie auf die *Eintrag hinzufügen*-Schaltfläche (+) in der Fußzeile der Tabelle." +msgstr "" #: ../../en_US/_plugins/calendar/sharing.rst:31 msgid "" "Enter the username or choose one from the autocompletion menu that appears " "when you start typing. Instead of a specific user, permissons can be granted" " for all users or guests." -msgstr "Geben Sie den Benutzername ein oder wählen Sie einen aus dem Autovervollständigungs-Menü aus, das erscheint, wenn Sie zu tippen beginnen. Statt einem bestimmten Benutzer können Erlaubnisse auch allen Benutzern oder Gästen gewährt werden." +msgstr "" #: ../../en_US/_plugins/calendar/sharing.rst:33 msgid "Select the access rights you want to grant for the user" -msgstr "Wählen Sie die Zugangsberechtigungen, die Sie dem Benutzer gewähren wollen." +msgstr "" #: ../../en_US/_plugins/calendar/sharing.rst:34 msgid "Click *Save* to add the permission" -msgstr "Klicken Sie auf *Speichern*, um die Erlaubnis hinzuzufügen." +msgstr "" #: ../../en_US/_plugins/calendar/sharing.rst:36 msgid "" "Double-click an entry to edit the permissions for a particular user or " "group." -msgstr "Doppelklicken Sie einen Eintrag, um Erlaubnisse für einen bestimmten Benutzer oder eine bestimmte Gruppe zu bearbeiten." +msgstr "" #: ../../en_US/_plugins/calendar/sharing.rst:38 msgid "" "For removing existing permissions, select the according entry in the list " "and then choose *Delete* from the menu behind the gear icon in the footer of" " the list." -msgstr "Um bestehende Freigaben zu entfernen, wählen Sie den entsprechenden Eintrag in der Liste aus und wählen dann *Löschen* aus dem Menü hinter dem Zahnradicon in der Fußzeile der Liste aus." +msgstr "" #: ../../en_US/_plugins/calendar/sharing.rst:43 msgid "Subscribe to Shared Calendars" -msgstr "Geteilte Kalender abonnieren" +msgstr "" #: ../../en_US/_plugins/calendar/sharing.rst:45 msgid "" @@ -92,11 +89,11 @@ msgid "" " see all resources you can access. There's a shortcut to this: click *Manage" " folders* in the options menu behind the gear icon located the footer of the" " calendars list." -msgstr "Von anderen geteilte Kalender tauchen nicht sofort in der Liste innerhalb der Kalenderansicht auf. Wechseln Sie zu :ref:`Einstellungen > Ordner `, um alle Hilfsmittel zu sehen, auf die Sie zugreifen können. Es gibt auch einen kürzeren Weg dorthin: Klicken Sie auf *Ordner verwalten* im Optionsmenü hinter dem Zahnradicon in der Fußzeile der Kalenderliste." +msgstr "" #: ../../en_US/_plugins/calendar/sharing.rst:50 msgid "" "In order to make a shared calendar appear in the calendars list, locate it " "in the folder manager and check the *Subscribed* mark in the list. Only " "subscribed calendars are visible in the calendar view." -msgstr "Um einen geteilten Kalender in der Kalenderliste erscheinen zu lassen, suchen Sie ihn in der Ordnerverwaltung und versehen Sie das *Abonniert*-Kästchen in der Liste mit einem Häkchen. Nur abonnierte Kalender sind in der Kalenderansicht sichtbar." +msgstr "" diff --git a/plugins/kolab_addressbook/helpdocs/locale/de_DE/LC_MESSAGES/addressbook.po b/plugins/kolab_addressbook/helpdocs/locale/de_DE/LC_MESSAGES/addressbook.po index 82aa3a21..10c984af 100644 --- a/plugins/kolab_addressbook/helpdocs/locale/de_DE/LC_MESSAGES/addressbook.po +++ b/plugins/kolab_addressbook/helpdocs/locale/de_DE/LC_MESSAGES/addressbook.po @@ -3,66 +3,63 @@ # This file is distributed under the same license as the Roundcube Webmail Help package. # # Translators: -# Ettore Atalan , 2014 -# Mads , 2016 -# Max Hellwig , 2016 msgid "" msgstr "" "Project-Id-Version: Kolab Documentation\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-11-26 23:28+0100\n" -"PO-Revision-Date: 2017-09-23 20:32+0000\n" -"Last-Translator: Mads \n" -"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"PO-Revision-Date: 2014-11-27 23:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: German (Germany) (http://www.transifex.com/kolab/kolab-documentation/language/de_DE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: de\n" +"Language: de_DE\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:9 msgid "Sharing Address Books" -msgstr "Adressbücher teilen" +msgstr "" #: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:11 msgid "" "Just like calendars or regular email folders, personal address books can " "also be shared with other users in your workgroup." -msgstr "Persönliche Adressbücher können genauso wie Kalender oder normale E-Mail-Ordner mit anderen Nutzern Ihrer Arbeitsgruppe geteilt werden. " +msgstr "" #: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:16 msgid "Share Contacts with others" -msgstr "Kontakte mit Anderen teilen" +msgstr "" #: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:22 msgid "" "Settings for sharing is controlled through the address book properties " "accessible through the *More actions* menu behind the gear icon the footer " "in the :ref:`addressbook-groups` list." -msgstr "Die Einstellungen zum Teilen werden über die Eigenschaften des Adressbuchs gemacht, die durch das *Weitere Tätigkeiten*-Menü hinter dem Zahnradicon in der Fußzeile der :ref: `Adressbuchgruppen `-Liste zu erreichen sind. " +msgstr "" #: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:25 msgid "Select the address book you want to share." -msgstr "Wählen Sie das Adressbuch aus, dass Sie teilen möchten." +msgstr "" #: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:26 msgid "Choose *Edit address book* from the actions menu." -msgstr "Wählen Sie *Adressbuch bearbeiten* aus dem Tätigkeitenmenü. " +msgstr "" #: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:27 msgid "Switch to the *Sharing* tab in the properties form on the right." -msgstr "Wechseln Sie auf den *Teilen*-Reiter in der Eigenschaftenmaske rechts. " +msgstr "" #: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:29 msgid "" "The table displays who already has permission to see and modify the selected" " address book. Here you can manage permissions the same way as :ref:`Sharing" " a Folder `." -msgstr "Die Tabelle zeigt an, wer schon die Erlaubnis hat, das ausgewählte Adressbuch zu sehen und verändern. Freigaben können hier auf die selbe Weise, wie :ref: `Ordner teilen ` verwaltet werden. " +msgstr "" #: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:34 msgid "Subscribe to Shared Address Books" -msgstr "Geteilte Adressbücher abonnieren" +msgstr "" #: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:36 msgid "" @@ -71,11 +68,11 @@ msgid "" "` to see all resources you can access. There's a shortcut " "to this: click *Manage folders* in the actions menu behind the gear icon " "located the footer of the directory list." -msgstr "Adressbücher, die von anderen geteilt wurden, werden nicht sofort in der Verzeichnisliste des Webclients angezeigt. Wechseln Sie zu :ref: `Einstellungen > Ordner `, um alle Hilfsmittel, auf die Sie Zugriff haben, zu sehen. Es gibt einen schnelleren Weg dorthin: Klicken Sie auf *Ordner verwalten* im Tätigkeitenmenü hinter dem Zahnradicon in der Fußzeile der Verzeichnisliste. " +msgstr "" #: ../../en_US/_plugins/kolab_addressbook/addressbook.rst:41 msgid "" "In order to make a shared address book appear in the address book view, " "locate it in the folder manager and check the *Subscribed* mark in the list." " Only subscribed directories are visible in the address book view." -msgstr "Um ein geteiltes Adressbuch in der Adressbuchansicht anzuzeigen, wählen Sie es in der Ordnerverwaltung aus und setzen Sie bei *Abonniert* ein Häkchen in der Liste. Nur abonnierte Verzeichnisse sind in der Adressbuchansicht sichtbar. " +msgstr "" diff --git a/plugins/tasklist/helpdocs/locale/de_DE/LC_MESSAGES/index.po b/plugins/tasklist/helpdocs/locale/de_DE/LC_MESSAGES/index.po index cb5214ab..cca2f35a 100644 --- a/plugins/tasklist/helpdocs/locale/de_DE/LC_MESSAGES/index.po +++ b/plugins/tasklist/helpdocs/locale/de_DE/LC_MESSAGES/index.po @@ -3,27 +3,26 @@ # This file is distributed under the same license as the Roundcube Webmail Help package. # # Translators: -# Mads , 2016 msgid "" msgstr "" "Project-Id-Version: Kolab Documentation\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-11-26 23:28+0100\n" -"PO-Revision-Date: 2017-09-23 20:32+0000\n" -"Last-Translator: Mads \n" -"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"PO-Revision-Date: 2014-11-27 23:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: German (Germany) (http://www.transifex.com/kolab/kolab-documentation/language/de_DE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: de\n" +"Language: de_DE\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../../en_US/_plugins/tasks/index.rst:9 msgid "Tasks" -msgstr "Aufgaben" +msgstr "" #: ../../en_US/_plugins/tasks/index.rst:11 msgid "" "The *Tasks* module helps you organize your daily jobs and ToDo's and will " "alert you about upcoming deadlines." -msgstr "Das *Aufgaben*-Modul hilft Ihnen, Ihre täglichen Aufgaben und Pendenzen zu organisieren und meldet Ihnen bevorstehende Fristen. " +msgstr "" diff --git a/plugins/tasklist/helpdocs/locale/de_DE/LC_MESSAGES/manage.po b/plugins/tasklist/helpdocs/locale/de_DE/LC_MESSAGES/manage.po index 39346955..1e9740bf 100644 --- a/plugins/tasklist/helpdocs/locale/de_DE/LC_MESSAGES/manage.po +++ b/plugins/tasklist/helpdocs/locale/de_DE/LC_MESSAGES/manage.po @@ -3,39 +3,37 @@ # This file is distributed under the same license as the Roundcube Webmail Help package. # # Translators: -# Ettore Atalan , 2014 -# Gerd Seyfarth , 2015 msgid "" msgstr "" "Project-Id-Version: Kolab Documentation\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-11-26 23:28+0100\n" -"PO-Revision-Date: 2017-09-23 20:32+0000\n" -"Last-Translator: Jeroen van Meeuwen \n" -"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"PO-Revision-Date: 2014-11-27 23:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: German (Germany) (http://www.transifex.com/kolab/kolab-documentation/language/de_DE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: de\n" +"Language: de_DE\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../../en_US/_plugins/tasks/manage.rst:7 msgid "Managing Tasks" -msgstr "Aufgaben verwalten" +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:9 msgid "" "All the described functions to manage your tasks are accessible from the " "main task view." -msgstr "Alle beschriebenen Funktionen zum Verwalten Ihrer Aufgaben sind in der Hauptaufgabenansicht zugänglich." +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:13 msgid "Create new Tasks" -msgstr "Neue Aufgaben erstellen" +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:18 msgid "**The New Task Dialog**" -msgstr "**Der Dialog für neue Aufgaben**" +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:16 msgid "" @@ -46,7 +44,7 @@ msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:27 msgid "**Quick Entry**" -msgstr "**Schnelleintrag**" +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:21 msgid "" @@ -63,11 +61,11 @@ msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:32 msgid "Edit Tasks" -msgstr "Aufgaben bearbeiten" +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:35 msgid "The Edit Dialog" -msgstr "Der Bearbeitungsdialog" +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:37 msgid "" @@ -84,7 +82,7 @@ msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:42 msgid "**Summary**" -msgstr "**Zusammenfassung**" +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:44 msgid "" @@ -95,13 +93,13 @@ msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:46 msgid "" "``Title``: The title of the task. This is what you will see in the list." -msgstr "``Titel``: Der Titel der Aufgabe. Das ist was Sie in der Liste sehen werden." +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:47 msgid "" "``Description``: Any text that describes the task. Links and email addresses" " will be become clickable." -msgstr "``Beschreibung``: Jeder Text, der die Aufgabe beschreibt. Links und E-Mail-Adressen werden anklickbar." +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:48 msgid "" @@ -139,7 +137,7 @@ msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:58 msgid "**Attachments**" -msgstr "**Anhänge**" +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:60 msgid "" @@ -210,7 +208,7 @@ msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:107 msgid "Mark Tasks as Complete" -msgstr "Aufgaben als abgeschlossen markieren" +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:109 msgid "" @@ -230,7 +228,7 @@ msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:120 msgid "Organize Tasks in Groups" -msgstr "Aufgaben in Gruppen organisieren" +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:122 msgid "" @@ -240,7 +238,7 @@ msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:126 msgid "Create a Subtask" -msgstr "Teilaufgabe erstellen" +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:132 #: ../../en_US/_plugins/tasks/manage.rst:172 @@ -251,7 +249,7 @@ msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:133 msgid "Select *Add subtask*" -msgstr "*Teilaufgabe hinzufügen* auswählen" +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:134 msgid "" @@ -264,7 +262,7 @@ msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:141 msgid "Re-organize Groups" -msgstr "Gruppen umorganisieren" +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:143 msgid "" @@ -289,7 +287,7 @@ msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:157 msgid "Get Notifications" -msgstr "Benachrichtigungen holen" +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:159 msgid "" @@ -308,7 +306,7 @@ msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:167 msgid "Delete Tasks" -msgstr "Aufgaben löschen" +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:169 msgid "" @@ -318,8 +316,8 @@ msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:173 msgid "Select *Delete*." -msgstr "*Löschen* auswählen." +msgstr "" #: ../../en_US/_plugins/tasks/manage.rst:174 msgid "Click *Delete* again in the confirmation dialog." -msgstr "Klicken Sie im Bestätigungsdialog erneut auf *Löschen*." +msgstr "" diff --git a/plugins/tasklist/helpdocs/locale/de_DE/LC_MESSAGES/overview.po b/plugins/tasklist/helpdocs/locale/de_DE/LC_MESSAGES/overview.po index 4bec001e..c5f01701 100644 --- a/plugins/tasklist/helpdocs/locale/de_DE/LC_MESSAGES/overview.po +++ b/plugins/tasklist/helpdocs/locale/de_DE/LC_MESSAGES/overview.po @@ -3,24 +3,23 @@ # This file is distributed under the same license as the Roundcube Webmail Help package. # # Translators: -# Ettore Atalan , 2014 msgid "" msgstr "" "Project-Id-Version: Kolab Documentation\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-11-26 23:28+0100\n" -"PO-Revision-Date: 2017-09-23 20:32+0000\n" -"Last-Translator: Jeroen van Meeuwen \n" -"Language-Team: German (http://www.transifex.com/kolab/kolab-documentation/language/de/)\n" +"PO-Revision-Date: 2014-11-27 23:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: German (Germany) (http://www.transifex.com/kolab/kolab-documentation/language/de_DE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: de\n" +"Language: de_DE\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../../en_US/_plugins/tasks/overview.rst:6 msgid "Overview" -msgstr "Übersicht" +msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:8 msgid "" @@ -31,7 +30,7 @@ msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:16 msgid "The Tasks List" -msgstr "Die Aufgabenliste" +msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:18 msgid "" @@ -66,11 +65,11 @@ msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:39 msgid "Control the List" -msgstr "Listensteuerung" +msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:42 msgid "Quick Filters" -msgstr "Schnellfilter" +msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:44 msgid "" @@ -81,7 +80,7 @@ msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:50 msgid "Tags" -msgstr "Schlagworte" +msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:52 msgid "" @@ -94,7 +93,7 @@ msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:57 #: ../../en_US/_plugins/tasks/overview.rst:83 msgid "Task Lists" -msgstr "Aufgabenliste" +msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:59 msgid "" @@ -108,7 +107,7 @@ msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:68 msgid "Searching Tasks" -msgstr "Aufgabensuche" +msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:70 msgid "" @@ -145,7 +144,7 @@ msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:92 msgid "Create a Task List" -msgstr "Aufgabenliste erstellten" +msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:94 msgid "Click the + icon in the tasklists box footer." @@ -157,11 +156,11 @@ msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:96 msgid "Click *Save* to create it." -msgstr "Klicken Sie auf *Speichern* zum Erstellen." +msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:101 msgid "Edit List Names and Settings" -msgstr "Listennamen und Einstellungen bearbeiten" +msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:103 #: ../../en_US/_plugins/tasks/overview.rst:111 @@ -184,7 +183,7 @@ msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:109 msgid "Remove entire Task Lists" -msgstr "Gesamte Aufgabenliste entfernen" +msgstr "" #: ../../en_US/_plugins/tasks/overview.rst:112 msgid "" From ac7b742005eebbf4c7686da607ebaf50c8e53aa6 Mon Sep 17 00:00:00 2001 From: "Jeroen van Meeuwen (Kolab Systems)" Date: Wed, 19 Dec 2018 10:09:03 +0100 Subject: [PATCH 04/98] Update the base translations before merge --- plugins/calendar/localization/de.inc | 269 ++++++++++++++++++ plugins/calendar/localization/de_DE.inc | 241 +++++----------- plugins/kolab_2fa/localization/de.inc | 16 ++ plugins/kolab_2fa/localization/de_DE.inc | 1 - plugins/kolab_activesync/localization/de.inc | 33 +++ .../kolab_activesync/localization/de_DE.inc | 23 -- plugins/kolab_addressbook/localization/de.inc | 66 +++++ .../kolab_addressbook/localization/de_DE.inc | 58 ++-- plugins/kolab_auth/localization/de.inc | 11 + plugins/kolab_auth/localization/de_DE.inc | 2 +- .../localization/{de_DE.inc => de.inc} | 0 plugins/kolab_delegation/localization/de.inc | 36 +++ .../kolab_delegation/localization/de_DE.inc | 20 +- plugins/kolab_files/localization/de.inc | 152 ++++++++++ plugins/kolab_files/localization/de_DE.inc | 134 +-------- plugins/kolab_folders/localization/de.inc | 30 ++ plugins/kolab_folders/localization/de_DE.inc | 11 +- plugins/kolab_notes/localization/de.inc | 62 ++++ plugins/kolab_notes/localization/de_DE.inc | 43 +-- plugins/kolab_tags/localization/de.inc | 34 +++ plugins/kolab_tags/localization/de_DE.inc | 22 +- plugins/libcalendaring/localization/de.inc | 162 +++++++++++ plugins/libcalendaring/localization/de_DE.inc | 171 ++++------- plugins/libkolab/localization/de.inc | 25 ++ plugins/libkolab/localization/de_DE.inc | 17 +- plugins/tasklist/localization/de.inc | 192 +++++++++++++ plugins/tasklist/localization/de_DE.inc | 170 +++-------- 27 files changed, 1298 insertions(+), 703 deletions(-) create mode 100644 plugins/calendar/localization/de.inc create mode 100644 plugins/kolab_2fa/localization/de.inc create mode 100644 plugins/kolab_activesync/localization/de.inc create mode 100644 plugins/kolab_addressbook/localization/de.inc create mode 100644 plugins/kolab_auth/localization/de.inc rename plugins/kolab_chat/localization/{de_DE.inc => de.inc} (100%) create mode 100644 plugins/kolab_delegation/localization/de.inc create mode 100644 plugins/kolab_files/localization/de.inc create mode 100644 plugins/kolab_folders/localization/de.inc create mode 100644 plugins/kolab_notes/localization/de.inc create mode 100644 plugins/kolab_tags/localization/de.inc create mode 100644 plugins/libcalendaring/localization/de.inc create mode 100644 plugins/libkolab/localization/de.inc create mode 100644 plugins/tasklist/localization/de.inc diff --git a/plugins/calendar/localization/de.inc b/plugins/calendar/localization/de.inc new file mode 100644 index 00000000..1981504e --- /dev/null +++ b/plugins/calendar/localization/de.inc @@ -0,0 +1,269 @@ +CalDAV-Klienten (z.B. Evolution oder Mozilla Thunderbird) kopieren, um den Kalender in Gänze mit einem mobilen Gerät zu synchronisieren.'; +$labels['findcalendars'] = 'Kalender finden …'; +$labels['searchterms'] = 'Suchbegriffe'; +$labels['calsearchresults'] = 'Verfügbare Kalender'; +$labels['calendarsubscribe'] = 'Permanent anzeigen'; +$labels['nocalendarsfound'] = 'Keine Kalender gefunden'; +$labels['nrcalendarsfound'] = '$nr Kalender gefunden'; +$labels['quickview'] = 'Nur diesen Kalender anzeigen'; +$labels['invitationspending'] = 'Ausstehende Einladungen'; +$labels['invitationsdeclined'] = 'Abgelehnte Einladungen'; +$labels['changepartstat'] = 'Teilnehmerstatus ändern'; +$labels['rsvpcomment'] = 'Einladungstext'; +$labels['listrange'] = 'Angezeigter Bereich:'; +$labels['listsections'] = 'Unterteilung:'; +$labels['smartsections'] = 'Intelligent'; +$labels['until'] = 'bis'; +$labels['today'] = 'Heute'; +$labels['tomorrow'] = 'Morgen'; +$labels['thisweek'] = 'Diese Woche'; +$labels['nextweek'] = 'Nächste Woche'; +$labels['prevweek'] = 'Vorige Woche'; +$labels['thismonth'] = 'Diesen Monat'; +$labels['nextmonth'] = 'Nächsten Monat'; +$labels['weekofyear'] = 'Woche'; +$labels['pastevents'] = 'Vergangene'; +$labels['futureevents'] = 'Zukünftige'; +$labels['showalarms'] = 'Erinnerungen anzeigen'; +$labels['defaultalarmtype'] = 'Standard-Erinnerungseinstellung'; +$labels['defaultalarmoffset'] = 'Standard-Erinnerungszeit'; +$labels['attendee'] = 'Teilnehmer'; +$labels['role'] = 'Rolle'; +$labels['availability'] = 'Verfüg.'; +$labels['confirmstate'] = 'Status'; +$labels['addattendee'] = 'Hinzufügen'; +$labels['roleorganizer'] = 'Organisator'; +$labels['rolerequired'] = 'Erforderlich'; +$labels['roleoptional'] = 'Optional'; +$labels['rolechair'] = 'Vorsitz'; +$labels['rolenonparticipant'] = 'Abwesend'; +$labels['cutypeindividual'] = 'Person'; +$labels['cutypegroup'] = 'Gruppe'; +$labels['cutyperesource'] = 'Ressource'; +$labels['cutyperoom'] = 'Raum'; +$labels['availfree'] = 'Frei'; +$labels['availbusy'] = 'Gebucht'; +$labels['availunknown'] = 'Unbekannt'; +$labels['availtentative'] = 'Mit Vorbehalt'; +$labels['availoutofoffice'] = 'Abwesend'; +$labels['scheduletime'] = 'Verfügbarkeit anzeigen'; +$labels['sendinvitations'] = 'Einladungen versenden'; +$labels['sendnotifications'] = 'Teilnehmer über die Änderungen informieren'; +$labels['sendcancellation'] = 'Teilnehmer über die Terminabsage informieren'; +$labels['onlyworkinghours'] = 'Verfügbarkeit innerhalb meiner Arbeitszeiten suchen'; +$labels['reqallattendees'] = 'Erforderliche/alle Teilnehmer'; +$labels['prevslot'] = 'Vorheriger Vorschlag'; +$labels['nextslot'] = 'Nächster Vorschlag'; +$labels['suggestedslot'] = 'Empfohlener Slot'; +$labels['noslotfound'] = 'Es konnten keine freien Zeiten gefunden werden'; +$labels['invitationsubject'] = 'Sie wurden zu »$title« eingeladen'; +$labels['invitationmailbody'] = "*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees\n\n\$description\n\nIm Anhang finden Sie eine iCalendar-Datei mit allen Details des Termins. Diese können Sie in Ihre Kalenderanwendung importieren."; +$labels['invitationattendlinks'] = "Falls Ihr E-Mail-Programm keine iTip-Anfragen unterstützt, können Sie den folgenden Link verwenden, um den Termin zu bestätigen oder abzulehnen:\n\$url"; +$labels['eventupdatesubject'] = '»$title« wurde aktualisiert'; +$labels['eventupdatesubjectempty'] = 'Termin wurde aktualisiert'; +$labels['eventupdatemailbody'] = "*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees\n\nIm Anhang finden Sie eine iCalendar-Datei mit den aktualisiereten Termindaten. Diese können Sie in Ihre Kalenderanwendung importieren."; +$labels['eventcancelsubject'] = '»$title« wurde abgesagt'; +$labels['eventcancelmailbody'] = "*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees\n\nDer Termin wurde von \$organizer abgesagt.\n\nIm Anhang finden Sie eine iCalendar-Datei mit den Termindaten."; +$labels['itipobjectnotfound'] = 'Der Termin auf den sich diese Nachricht bezieht, wurde in Ihrem Kalender nicht gefunden.'; +$labels['itipmailbodyaccepted'] = "\$sender hat die Einladung zum folgenden Termin angenommen:\n\n*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees"; +$labels['itipmailbodytentative'] = "\$sender hat die Einladung mit Vorbehalt zum folgenden Termin angenommen:\n\n*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees"; +$labels['itipmailbodydeclined'] = "\$sender hat die Einladung zum folgenden Termin abgelehnt:\n\n*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees"; +$labels['itipmailbodycancel'] = "\$sender hat Ihre Teilnahme bei der folgenden Veranstaltung zurückgewiesen:\n\n*\$title*\n\nWann: \$date"; +$labels['itipmailbodydelegated'] = "\$sender hat die Teilnahme an folgendem Event delegiert:\n\n*\$title*\n\nWhen: \$date"; +$labels['itipmailbodydelegatedto'] = "\$sender hat die Teilnahme an folgendem Event an Sie delegiert:\n\n*\$title*\n\nWann: \$date"; +$labels['itipdeclineevent'] = 'Möchten Sie die Einladung zu diesem Termin ablehnen?'; +$labels['declinedeleteconfirm'] = 'Soll der abgelehnte Termin zusätzlich aus dem Kalender gelöscht werden?'; +$labels['itipcomment'] = 'Kommentar zur Einladungs-/Benachrichtigungsnachricht'; +$labels['itipcommenttitle'] = 'Dieser Kommentar wird an die Einladungs-/Benachrichtigungsnachricht angehängt, die an die Teilnehmer verschickt wird'; +$labels['notanattendee'] = 'Sie sind nicht in der Liste der Teilnehmer aufgeführt'; +$labels['eventcancelled'] = 'Der Termin wurde vom Organisator abgesagt'; +$labels['saveincalendar'] = 'speichern in'; +$labels['updatemycopy'] = 'In meinem Kalender aktualisieren'; +$labels['savetocalendar'] = 'In Kalender übernehmen'; +$labels['openpreview'] = 'Kalender überprüfen'; +$labels['noearlierevents'] = 'Keine früheren Ereignisse'; +$labels['nolaterevents'] = 'Keine späteren Ereignisse'; +$labels['resource'] = 'Ressource'; +$labels['addresource'] = 'Ressource buchen'; +$labels['findresources'] = 'Ressourcen finden'; +$labels['resourcedetails'] = 'Details'; +$labels['resourceavailability'] = 'Verfügbarkeit'; +$labels['resourceowner'] = 'Eigentümer'; +$labels['resourceadded'] = 'Diese Ressource wurde Ihrem Termin hinzugefügt'; +$labels['tabsummary'] = 'Übersicht'; +$labels['tabrecurrence'] = 'Wiederholung'; +$labels['tabattendees'] = 'Teilnehmer'; +$labels['tabresources'] = 'Ressourcen'; +$labels['tabattachments'] = 'Anhänge'; +$labels['tabsharing'] = 'Freigabe'; +$labels['deleteobjectconfirm'] = 'Möchten Sie diesen Termin wirklich löschen?'; +$labels['deleteventconfirm'] = 'Möchten Sie diesen Termin wirklich löschen?'; +$labels['deletecalendarconfirm'] = 'Möchten Sie diesen Kalender mit allen Terminen wirklich löschen?'; +$labels['deletecalendarconfirmrecursive'] = 'Soll dieser Kalender wirklich mit allen Terminen und Unterkalendern gelöscht werden?'; +$labels['savingdata'] = 'Daten werden gespeichert …'; +$labels['errorsaving'] = 'Fehler beim Speichern.'; +$labels['operationfailed'] = 'Die Aktion ist fehlgeschlagen.'; +$labels['invalideventdates'] = 'Ungültige Daten eingegeben! Bitte überprüfen Sie die Eingaben.'; +$labels['invalidcalendarproperties'] = 'Ungültige Kalenderinformationen! Bitte geben Sie einen Namen ein.'; +$labels['searchnoresults'] = 'Keine Termine in den gewählten Kalendern gefunden.'; +$labels['successremoval'] = 'Der Termin wurde erfolgreich gelöscht.'; +$labels['successrestore'] = 'Der Termin wurde erfolgreich wieder hergestellt.'; +$labels['errornotifying'] = 'Benachrichtigung an die Teilnehmer konnten nicht gesendet werden'; +$labels['errorimportingevent'] = 'Fehler beim Importieren'; +$labels['importwarningexists'] = 'Eine Kopie dieses Termins existiert bereits in Ihrem Kalender.'; +$labels['newerversionexists'] = 'Eine neuere Version dieses Termins exisitert bereits! Import abgebrochen.'; +$labels['nowritecalendarfound'] = 'Kein Kalender zum Speichern gefunden'; +$labels['importedsuccessfully'] = 'Der Termin wurde erfolgreich in »$calendar« gespeichert'; +$labels['updatedsuccessfully'] = 'Der Termin wurde erfolgreich in »$calendar« geändert'; +$labels['attendeupdateesuccess'] = 'Teilnehmerstatus erfolgreich aktualisiert'; +$labels['itipsendsuccess'] = 'Einladung an Teilnehmer versendet.'; +$labels['itipresponseerror'] = 'Die Antwort auf diese Einladung konnte nicht versendet werden'; +$labels['itipinvalidrequest'] = 'Diese Einladung ist nicht mehr gültig.'; +$labels['sentresponseto'] = 'Antwort auf diese Einladung erfolgreich an $mailto gesendet'; +$labels['localchangeswarning'] = 'Die auszuführenden Änderungen werden sich nur auf den persönlichen Kalender auswirken und nicht an den Organisator des Termins weitergeleitet.'; +$labels['importsuccess'] = 'Es wurden $nr Termine erfolgreich importiert'; +$labels['importnone'] = 'Keine Termine zum Importieren gefunden'; +$labels['importerror'] = 'Fehler beim Importieren'; +$labels['aclnorights'] = 'Der Zugriff auf diesen Kalender erfordert Administrator-Rechte.'; +$labels['changeeventconfirm'] = 'Termin ändern'; +$labels['removeeventconfirm'] = 'Termin löschen'; +$labels['changerecurringeventwarning'] = 'Dies ist eine Terminreihe. Möchten Sie nur den aktuellen, diesen und alle zukünftigen oder alle Termine bearbeiten oder die Änderungen als neuen Termin speichern?'; +$labels['removerecurringeventwarning'] = 'Dies ist ein wiederkehrender Termin. Wollen Sie nur diesen Termin bearbeiten oder alle zukünftigen Vorkommen? Alternativ können auch alle Vorkommen bearbeitet werden.'; +$labels['removerecurringallonly'] = 'Dieses ist ein wiederkehrender Termin. Als ein Teilnehmer können Sie nur den gesamten Termin inklusive aller Wiederholungen löschen.'; +$labels['currentevent'] = 'Aktuellen'; +$labels['futurevents'] = 'Zukünftige'; +$labels['allevents'] = 'Alle'; +$labels['saveasnew'] = 'Als neu speichern'; +$labels['birthdays'] = 'Geburtstage'; +$labels['birthdayscalendar'] = 'Geburtstagskalender'; +$labels['displaybirthdayscalendar'] = 'Geburtstagskalender anzeigen'; +$labels['birthdayscalendarsources'] = 'Für diese Adressbücher'; +$labels['birthdayeventtitle'] = '$names Geburtstag'; +$labels['birthdayage'] = 'Alter $age'; +$labels['objectchangelog'] = 'Änderungsverlauf'; +$labels['objectdiff'] = 'Änderungen aus $rev1 nach $rev2'; +$labels['objectnotfound'] = 'Termindaten sind leider nicht vergübar'; +$labels['objectchangelognotavailable'] = 'Änderungshistorie ist nicht verfügbar für diesen Termin'; +$labels['objectdiffnotavailable'] = 'Vergleich für die gewählten Versionen nicht möglich'; +$labels['revisionrestoreconfirm'] = 'Wollen Sie wirklich die Version $rev dieses Termins wiederherstellen? Diese Aktion wird die aktuelle Kopie mit der älteren Version ersetzen.'; +$labels['objectrestoresuccess'] = 'Revision $rev erfolgreich wiederhergestellt'; +$labels['objectrestoreerror'] = 'Fehler beim Wiederherstellen der alten Revision'; +$labels['arialabelminical'] = 'Kalender Datumswahl'; +$labels['arialabelcalendarview'] = 'Kalender Ansicht'; +$labels['arialabelsearchform'] = 'Suchformular für Termine'; +$labels['arialabelquicksearchbox'] = 'Sucheingabe für Termine'; +$labels['arialabelcalsearchform'] = 'Suchformular für Kalender'; +$labels['calendaractions'] = 'Kalenderaktionen'; +$labels['arialabeleventattendees'] = 'Teilehmerliste'; +$labels['arialabeleventresources'] = 'Liste der Terminressourcen'; +$labels['arialabelresourcesearchform'] = 'Suchformular für Ressourcen'; +$labels['arialabelresourceselection'] = 'Verfügbare Ressourcen'; +?> diff --git a/plugins/calendar/localization/de_DE.inc b/plugins/calendar/localization/de_DE.inc index 1981504e..6682f28f 100644 --- a/plugins/calendar/localization/de_DE.inc +++ b/plugins/calendar/localization/de_DE.inc @@ -7,27 +7,19 @@ * For translation see https://www.transifex.com/projects/p/kolab/resource/calendar/ */ $labels['default_view'] = 'Standardansicht'; -$labels['time_format'] = 'Zeitformatierung'; +$labels['time_format'] = 'Zeitformat'; $labels['timeslots'] = 'Zeitfenster pro Stunde'; $labels['first_day'] = 'Erster Wochentag'; -$labels['first_hour'] = 'Erste angezeigte Stunde'; -$labels['workinghours'] = 'Arbeitszeiten'; +$labels['first_hour'] = 'Erste anzuzeigende Stunde'; +$labels['workinghours'] = 'Arbeitszeit'; $labels['add_category'] = 'Kategorie hinzufügen'; $labels['remove_category'] = 'Kategorie entfernen'; -$labels['defaultcalendar'] = 'Neue Termine erstellen in'; -$labels['eventcoloring'] = 'Färbung der Termine'; -$labels['coloringmode0'] = 'Farbe des Kalenders'; -$labels['coloringmode1'] = 'Farbe der Kategorie'; -$labels['coloringmode2'] = 'Kalenderfarbe außen, Kategoriefarbe innen'; -$labels['coloringmode3'] = 'Kategoriefarbe außen, Kalenderfarbe innen'; -$labels['afternothing'] = 'nichts unternehmen'; +$labels['defaultcalendar'] = 'Erstelle neue Termine in'; $labels['aftertrash'] = 'In den Papierkorb verschieben'; -$labels['afterdelete'] = 'Nachricht löschen'; -$labels['afterflagdeleted'] = 'Als gelöscht markieren'; -$labels['aftermoveto'] = 'Verschiebe nach...'; -$labels['itipoptions'] = 'Veranstaltungseinladungen'; -$labels['afteraction'] = 'Nachdem eine Einladungs- oder Aktualisierungsnachricht verarbeitet wurde'; -$labels['weeknonone'] = 'nie'; +$labels['afterdelete'] = 'Die Nachricht löschen'; +$labels['afterflagdeleted'] = 'Als gelöscht kennzeichnen'; +$labels['aftermoveto'] = 'Verschieben nach...'; +$labels['weeknonone'] = 'niemals'; $labels['calendar'] = 'Kalender'; $labels['calendars'] = 'Kalender'; $labels['category'] = 'Kategorie'; @@ -45,225 +37,144 @@ $labels['new_event'] = 'Neuer Termin'; $labels['edit_event'] = 'Termin bearbeiten'; $labels['edit'] = 'Bearbeiten'; $labels['save'] = 'Speichern'; -$labels['removelist'] = 'Von der Liste entfernen'; +$labels['removelist'] = 'Aus Liste entfernen'; $labels['cancel'] = 'Abbrechen'; $labels['select'] = 'Auswählen'; $labels['print'] = 'Drucken'; $labels['printtitle'] = 'Kalender drucken'; -$labels['title'] = 'Titel'; +$labels['title'] = 'Zusammenfassung'; $labels['description'] = 'Beschreibung'; $labels['all-day'] = 'ganztägig'; $labels['export'] = 'Exportieren'; -$labels['exporttitle'] = 'Kalender als iCalendar exportieren'; -$labels['exportrange'] = 'Termine ab'; +$labels['exporttitle'] = 'Nach iCalendar exportieren'; +$labels['exportrange'] = 'Termine von'; $labels['exportattachments'] = 'Mit Anhängen'; $labels['customdate'] = 'Benutzerdefiniertes Datum'; $labels['location'] = 'Ort'; -$labels['url'] = 'Internetadresse'; +$labels['url'] = 'URL'; $labels['date'] = 'Datum'; -$labels['start'] = 'Beginn'; -$labels['starttime'] = 'Startzeit'; +$labels['start'] = 'Start'; +$labels['starttime'] = 'Beginn'; $labels['end'] = 'Ende'; -$labels['endtime'] = 'Endzeit'; -$labels['repeat'] = 'Wiederholung'; -$labels['selectdate'] = 'Datum auswählen'; -$labels['freebusy'] = 'Mich anzeigen als'; +$labels['endtime'] = 'Ende'; +$labels['repeat'] = 'Wiederholen'; $labels['free'] = 'Frei'; -$labels['busy'] = 'Gebucht'; -$labels['outofoffice'] = 'Abwesend'; +$labels['busy'] = 'Beschäftigt'; $labels['tentative'] = 'Mit Vorbehalt'; $labels['mystatus'] = 'Mein Status'; $labels['status'] = 'Status'; $labels['status-confirmed'] = 'Bestätigt'; -$labels['status-cancelled'] = 'Abgesagt'; +$labels['status-cancelled'] = 'Gekündigt'; $labels['status-tentative'] = 'Mit Vorbehalt'; $labels['priority'] = 'Priorität'; -$labels['sensitivity'] = 'Sichtbarkeit'; +$labels['sensitivity'] = 'Privatsphäre'; $labels['public'] = 'öffentlich'; $labels['private'] = 'privat'; $labels['confidential'] = 'vertraulich'; -$labels['links'] = 'Referenz'; $labels['alarms'] = 'Erinnerung'; $labels['comment'] = 'Kommentar'; $labels['created'] = 'Erstellt'; -$labels['changed'] = 'Geändert'; +$labels['changed'] = 'Zuletzt bearbeitet'; $labels['unknown'] = 'Unbekannt'; $labels['eventoptions'] = 'Optionen'; -$labels['generated'] = 'erstellt am'; $labels['eventhistory'] = 'Historie'; -$labels['removelink'] = 'E-Mail-Referenz entfernen'; -$labels['printdescriptions'] = 'Beschreibung drucken'; -$labels['parentcalendar'] = 'Erstellen in'; -$labels['searchearlierdates'] = '« Frühere Termine suchen'; -$labels['searchlaterdates'] = 'Spätere Termine suchen »'; +$labels['searchearlierdates'] = '« Suche nach früheren Terminen'; +$labels['searchlaterdates'] = 'Suche nach späteren Terminen »'; $labels['laterevents'] = 'Später'; -$labels['andnmore'] = '$nr weitere …'; -$labels['togglerole'] = 'Zum Ändern der Rolle klicken'; +$labels['andnmore'] = '$nr mehr...'; $labels['createfrommail'] = 'Als Termin speichern'; $labels['importevents'] = 'Termine importieren'; -$labels['importrange'] = 'Termine ab'; +$labels['importrange'] = 'Termine von'; $labels['onemonthback'] = '1 Monat zurück'; $labels['nmonthsback'] = '$nr Monate zurück'; -$labels['showurl'] = 'URL anzeigen'; -$labels['showurldescription'] = 'Über die folgende Adresse können Sie mit einem beliebigen Kalenderprogramm Ihren Kalender abrufen (nur lesend), sofern dieses das iCal-Format unterstützt.'; -$labels['caldavurldescription'] = 'Diese Adresse in einen CalDAV-Klienten (z.B. Evolution oder Mozilla Thunderbird) kopieren, um den Kalender in Gänze mit einem mobilen Gerät zu synchronisieren.'; -$labels['findcalendars'] = 'Kalender finden …'; +$labels['showurl'] = 'Zeige Kalender-URL'; +$labels['caldavurldescription'] = 'Kopieren Sie diese Adresse in eine CalDAV-Client-Anwendung (z.B. Evolution oder Mozilla Thunderbird) um diesen Kalender mit Ihrem Computer oder Mobilgerät zu synchronisieren.'; +$labels['findcalendars'] = 'Finde Kalender...'; $labels['searchterms'] = 'Suchbegriffe'; $labels['calsearchresults'] = 'Verfügbare Kalender'; -$labels['calendarsubscribe'] = 'Permanent anzeigen'; $labels['nocalendarsfound'] = 'Keine Kalender gefunden'; $labels['nrcalendarsfound'] = '$nr Kalender gefunden'; -$labels['quickview'] = 'Nur diesen Kalender anzeigen'; $labels['invitationspending'] = 'Ausstehende Einladungen'; $labels['invitationsdeclined'] = 'Abgelehnte Einladungen'; -$labels['changepartstat'] = 'Teilnehmerstatus ändern'; +$labels['changepartstat'] = 'Status des Teilnehmers ändern'; $labels['rsvpcomment'] = 'Einladungstext'; -$labels['listrange'] = 'Angezeigter Bereich:'; -$labels['listsections'] = 'Unterteilung:'; -$labels['smartsections'] = 'Intelligent'; $labels['until'] = 'bis'; $labels['today'] = 'Heute'; $labels['tomorrow'] = 'Morgen'; $labels['thisweek'] = 'Diese Woche'; $labels['nextweek'] = 'Nächste Woche'; $labels['prevweek'] = 'Vorige Woche'; -$labels['thismonth'] = 'Diesen Monat'; -$labels['nextmonth'] = 'Nächsten Monat'; +$labels['thismonth'] = 'Dieser Monat'; +$labels['nextmonth'] = 'Nächster Monat'; $labels['weekofyear'] = 'Woche'; -$labels['pastevents'] = 'Vergangene'; -$labels['futureevents'] = 'Zukünftige'; -$labels['showalarms'] = 'Erinnerungen anzeigen'; -$labels['defaultalarmtype'] = 'Standard-Erinnerungseinstellung'; -$labels['defaultalarmoffset'] = 'Standard-Erinnerungszeit'; +$labels['pastevents'] = 'Vergangenheit'; +$labels['futureevents'] = 'Zukunft'; $labels['attendee'] = 'Teilnehmer'; -$labels['role'] = 'Rolle'; -$labels['availability'] = 'Verfüg.'; $labels['confirmstate'] = 'Status'; -$labels['addattendee'] = 'Hinzufügen'; -$labels['roleorganizer'] = 'Organisator'; -$labels['rolerequired'] = 'Erforderlich'; +$labels['addattendee'] = 'Teilnehmer hinzufügen'; +$labels['roleorganizer'] = 'Veranstalter'; +$labels['rolerequired'] = 'Pflichtfeld'; $labels['roleoptional'] = 'Optional'; -$labels['rolechair'] = 'Vorsitz'; +$labels['rolechair'] = 'Vorsitzender'; $labels['rolenonparticipant'] = 'Abwesend'; -$labels['cutypeindividual'] = 'Person'; $labels['cutypegroup'] = 'Gruppe'; -$labels['cutyperesource'] = 'Ressource'; +$labels['cutyperesource'] = 'Hilfsmittel'; $labels['cutyperoom'] = 'Raum'; $labels['availfree'] = 'Frei'; -$labels['availbusy'] = 'Gebucht'; +$labels['availbusy'] = 'Beschäftigt'; $labels['availunknown'] = 'Unbekannt'; $labels['availtentative'] = 'Mit Vorbehalt'; -$labels['availoutofoffice'] = 'Abwesend'; -$labels['scheduletime'] = 'Verfügbarkeit anzeigen'; -$labels['sendinvitations'] = 'Einladungen versenden'; -$labels['sendnotifications'] = 'Teilnehmer über die Änderungen informieren'; -$labels['sendcancellation'] = 'Teilnehmer über die Terminabsage informieren'; -$labels['onlyworkinghours'] = 'Verfügbarkeit innerhalb meiner Arbeitszeiten suchen'; -$labels['reqallattendees'] = 'Erforderliche/alle Teilnehmer'; -$labels['prevslot'] = 'Vorheriger Vorschlag'; -$labels['nextslot'] = 'Nächster Vorschlag'; -$labels['suggestedslot'] = 'Empfohlener Slot'; -$labels['noslotfound'] = 'Es konnten keine freien Zeiten gefunden werden'; -$labels['invitationsubject'] = 'Sie wurden zu »$title« eingeladen'; -$labels['invitationmailbody'] = "*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees\n\n\$description\n\nIm Anhang finden Sie eine iCalendar-Datei mit allen Details des Termins. Diese können Sie in Ihre Kalenderanwendung importieren."; -$labels['invitationattendlinks'] = "Falls Ihr E-Mail-Programm keine iTip-Anfragen unterstützt, können Sie den folgenden Link verwenden, um den Termin zu bestätigen oder abzulehnen:\n\$url"; -$labels['eventupdatesubject'] = '»$title« wurde aktualisiert'; -$labels['eventupdatesubjectempty'] = 'Termin wurde aktualisiert'; -$labels['eventupdatemailbody'] = "*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees\n\nIm Anhang finden Sie eine iCalendar-Datei mit den aktualisiereten Termindaten. Diese können Sie in Ihre Kalenderanwendung importieren."; -$labels['eventcancelsubject'] = '»$title« wurde abgesagt'; -$labels['eventcancelmailbody'] = "*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees\n\nDer Termin wurde von \$organizer abgesagt.\n\nIm Anhang finden Sie eine iCalendar-Datei mit den Termindaten."; -$labels['itipobjectnotfound'] = 'Der Termin auf den sich diese Nachricht bezieht, wurde in Ihrem Kalender nicht gefunden.'; -$labels['itipmailbodyaccepted'] = "\$sender hat die Einladung zum folgenden Termin angenommen:\n\n*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees"; -$labels['itipmailbodytentative'] = "\$sender hat die Einladung mit Vorbehalt zum folgenden Termin angenommen:\n\n*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees"; -$labels['itipmailbodydeclined'] = "\$sender hat die Einladung zum folgenden Termin abgelehnt:\n\n*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees"; -$labels['itipmailbodycancel'] = "\$sender hat Ihre Teilnahme bei der folgenden Veranstaltung zurückgewiesen:\n\n*\$title*\n\nWann: \$date"; -$labels['itipmailbodydelegated'] = "\$sender hat die Teilnahme an folgendem Event delegiert:\n\n*\$title*\n\nWhen: \$date"; -$labels['itipmailbodydelegatedto'] = "\$sender hat die Teilnahme an folgendem Event an Sie delegiert:\n\n*\$title*\n\nWann: \$date"; -$labels['itipdeclineevent'] = 'Möchten Sie die Einladung zu diesem Termin ablehnen?'; -$labels['declinedeleteconfirm'] = 'Soll der abgelehnte Termin zusätzlich aus dem Kalender gelöscht werden?'; -$labels['itipcomment'] = 'Kommentar zur Einladungs-/Benachrichtigungsnachricht'; -$labels['itipcommenttitle'] = 'Dieser Kommentar wird an die Einladungs-/Benachrichtigungsnachricht angehängt, die an die Teilnehmer verschickt wird'; -$labels['notanattendee'] = 'Sie sind nicht in der Liste der Teilnehmer aufgeführt'; -$labels['eventcancelled'] = 'Der Termin wurde vom Organisator abgesagt'; -$labels['saveincalendar'] = 'speichern in'; -$labels['updatemycopy'] = 'In meinem Kalender aktualisieren'; -$labels['savetocalendar'] = 'In Kalender übernehmen'; -$labels['openpreview'] = 'Kalender überprüfen'; -$labels['noearlierevents'] = 'Keine früheren Ereignisse'; -$labels['nolaterevents'] = 'Keine späteren Ereignisse'; -$labels['resource'] = 'Ressource'; -$labels['addresource'] = 'Ressource buchen'; -$labels['findresources'] = 'Ressourcen finden'; +$labels['prevslot'] = 'Vorheriges Zeitfenster'; +$labels['nextslot'] = 'Nächstes Zeitfenster'; +$labels['suggestedslot'] = 'Vorgeschlagenes Zeitfenster'; +$labels['noslotfound'] = 'Es konnte kein freies Zeitfenster gefunden werden'; +$labels['invitationattendlinks'] = "Falls Ihr Email-Client iTip-Anfragen nicht unterstützt können Sie den folgenden Link benutzen um die Einlaudng entweder abzulehnen oder anzunehmen:\n\$url"; +$labels['eventupdatesubject'] = '"$title" wurde aktualisiert'; +$labels['eventupdatesubjectempty'] = 'Ein Termin der sie betrifft wurde aktualisiert'; +$labels['eventcancelsubject'] = '"$title" wurde abgesagt'; +$labels['itipdeclineevent'] = 'Wollen Sie Ihre Einladung zu diesem Termin ablehnen?'; +$labels['declinedeleteconfirm'] = 'Möchten Sie den abgelehnten Termin außerdem aus Ihrem Kalender löschen?'; +$labels['eventcancelled'] = 'Der Termin wurde abgesagt'; +$labels['openpreview'] = 'Kalender prüfen'; +$labels['noearlierevents'] = 'Keine früheren Termine'; +$labels['nolaterevents'] = 'Keine späteren Termine'; +$labels['resource'] = 'Hilfsmittel'; +$labels['addresource'] = 'Hilfsmittel buchen'; +$labels['findresources'] = 'Hilfsmittel finden'; $labels['resourcedetails'] = 'Details'; $labels['resourceavailability'] = 'Verfügbarkeit'; $labels['resourceowner'] = 'Eigentümer'; -$labels['resourceadded'] = 'Diese Ressource wurde Ihrem Termin hinzugefügt'; -$labels['tabsummary'] = 'Übersicht'; +$labels['resourceadded'] = 'Das Hilfsmittel wurde ihrem Termin hinzugefügt'; +$labels['tabsummary'] = 'Zusammenfassung'; $labels['tabrecurrence'] = 'Wiederholung'; $labels['tabattendees'] = 'Teilnehmer'; $labels['tabresources'] = 'Ressourcen'; $labels['tabattachments'] = 'Anhänge'; -$labels['tabsharing'] = 'Freigabe'; $labels['deleteobjectconfirm'] = 'Möchten Sie diesen Termin wirklich löschen?'; $labels['deleteventconfirm'] = 'Möchten Sie diesen Termin wirklich löschen?'; -$labels['deletecalendarconfirm'] = 'Möchten Sie diesen Kalender mit allen Terminen wirklich löschen?'; -$labels['deletecalendarconfirmrecursive'] = 'Soll dieser Kalender wirklich mit allen Terminen und Unterkalendern gelöscht werden?'; -$labels['savingdata'] = 'Daten werden gespeichert …'; -$labels['errorsaving'] = 'Fehler beim Speichern.'; -$labels['operationfailed'] = 'Die Aktion ist fehlgeschlagen.'; -$labels['invalideventdates'] = 'Ungültige Daten eingegeben! Bitte überprüfen Sie die Eingaben.'; -$labels['invalidcalendarproperties'] = 'Ungültige Kalenderinformationen! Bitte geben Sie einen Namen ein.'; -$labels['searchnoresults'] = 'Keine Termine in den gewählten Kalendern gefunden.'; +$labels['deletecalendarconfirm'] = 'Möchten Sie diesen Kalender mit allen darin enthaltenen Terminen wirklich löschen?'; +$labels['deletecalendarconfirmrecursive'] = 'Möchten Sie diesen Kalender mit allen darin enthaltenen Terminen und enthaltenen Unterkalendern wirklich löschen?'; +$labels['savingdata'] = 'Daten werden gespeichert...'; +$labels['searchnoresults'] = 'Keine Termine in den ausgewählten Kalendern gefunden.'; $labels['successremoval'] = 'Der Termin wurde erfolgreich gelöscht.'; -$labels['successrestore'] = 'Der Termin wurde erfolgreich wieder hergestellt.'; -$labels['errornotifying'] = 'Benachrichtigung an die Teilnehmer konnten nicht gesendet werden'; -$labels['errorimportingevent'] = 'Fehler beim Importieren'; -$labels['importwarningexists'] = 'Eine Kopie dieses Termins existiert bereits in Ihrem Kalender.'; -$labels['newerversionexists'] = 'Eine neuere Version dieses Termins exisitert bereits! Import abgebrochen.'; -$labels['nowritecalendarfound'] = 'Kein Kalender zum Speichern gefunden'; -$labels['importedsuccessfully'] = 'Der Termin wurde erfolgreich in »$calendar« gespeichert'; -$labels['updatedsuccessfully'] = 'Der Termin wurde erfolgreich in »$calendar« geändert'; -$labels['attendeupdateesuccess'] = 'Teilnehmerstatus erfolgreich aktualisiert'; -$labels['itipsendsuccess'] = 'Einladung an Teilnehmer versendet.'; -$labels['itipresponseerror'] = 'Die Antwort auf diese Einladung konnte nicht versendet werden'; -$labels['itipinvalidrequest'] = 'Diese Einladung ist nicht mehr gültig.'; -$labels['sentresponseto'] = 'Antwort auf diese Einladung erfolgreich an $mailto gesendet'; -$labels['localchangeswarning'] = 'Die auszuführenden Änderungen werden sich nur auf den persönlichen Kalender auswirken und nicht an den Organisator des Termins weitergeleitet.'; -$labels['importsuccess'] = 'Es wurden $nr Termine erfolgreich importiert'; -$labels['importnone'] = 'Keine Termine zum Importieren gefunden'; -$labels['importerror'] = 'Fehler beim Importieren'; -$labels['aclnorights'] = 'Der Zugriff auf diesen Kalender erfordert Administrator-Rechte.'; +$labels['successrestore'] = 'Der Termin wurde erfolgreich wiederhergestellt.'; +$labels['itipsendsuccess'] = 'Einladung an die Teilnehmer versendet.'; +$labels['itipinvalidrequest'] = 'Die Einladung ist nicht länger gültig'; $labels['changeeventconfirm'] = 'Termin ändern'; $labels['removeeventconfirm'] = 'Termin löschen'; -$labels['changerecurringeventwarning'] = 'Dies ist eine Terminreihe. Möchten Sie nur den aktuellen, diesen und alle zukünftigen oder alle Termine bearbeiten oder die Änderungen als neuen Termin speichern?'; -$labels['removerecurringeventwarning'] = 'Dies ist ein wiederkehrender Termin. Wollen Sie nur diesen Termin bearbeiten oder alle zukünftigen Vorkommen? Alternativ können auch alle Vorkommen bearbeitet werden.'; -$labels['removerecurringallonly'] = 'Dieses ist ein wiederkehrender Termin. Als ein Teilnehmer können Sie nur den gesamten Termin inklusive aller Wiederholungen löschen.'; -$labels['currentevent'] = 'Aktuellen'; -$labels['futurevents'] = 'Zukünftige'; +$labels['futurevents'] = 'Zukunft'; $labels['allevents'] = 'Alle'; -$labels['saveasnew'] = 'Als neu speichern'; $labels['birthdays'] = 'Geburtstage'; $labels['birthdayscalendar'] = 'Geburtstagskalender'; -$labels['displaybirthdayscalendar'] = 'Geburtstagskalender anzeigen'; -$labels['birthdayscalendarsources'] = 'Für diese Adressbücher'; -$labels['birthdayeventtitle'] = '$names Geburtstag'; +$labels['displaybirthdayscalendar'] = 'Zeige Geburtstagskalender'; +$labels['birthdayeventtitle'] = 'Geburtstag von $name'; $labels['birthdayage'] = 'Alter $age'; -$labels['objectchangelog'] = 'Änderungsverlauf'; -$labels['objectdiff'] = 'Änderungen aus $rev1 nach $rev2'; -$labels['objectnotfound'] = 'Termindaten sind leider nicht vergübar'; -$labels['objectchangelognotavailable'] = 'Änderungshistorie ist nicht verfügbar für diesen Termin'; -$labels['objectdiffnotavailable'] = 'Vergleich für die gewählten Versionen nicht möglich'; -$labels['revisionrestoreconfirm'] = 'Wollen Sie wirklich die Version $rev dieses Termins wiederherstellen? Diese Aktion wird die aktuelle Kopie mit der älteren Version ersetzen.'; -$labels['objectrestoresuccess'] = 'Revision $rev erfolgreich wiederhergestellt'; -$labels['objectrestoreerror'] = 'Fehler beim Wiederherstellen der alten Revision'; -$labels['arialabelminical'] = 'Kalender Datumswahl'; -$labels['arialabelcalendarview'] = 'Kalender Ansicht'; -$labels['arialabelsearchform'] = 'Suchformular für Termine'; -$labels['arialabelquicksearchbox'] = 'Sucheingabe für Termine'; -$labels['arialabelcalsearchform'] = 'Suchformular für Kalender'; -$labels['calendaractions'] = 'Kalenderaktionen'; -$labels['arialabeleventattendees'] = 'Teilehmerliste'; -$labels['arialabeleventresources'] = 'Liste der Terminressourcen'; -$labels['arialabelresourcesearchform'] = 'Suchformular für Ressourcen'; -$labels['arialabelresourceselection'] = 'Verfügbare Ressourcen'; +$labels['objectchangelog'] = 'Änderungshistorie'; +$labels['objectdiff'] = 'Änderungen seit $rev1 bis $rev2'; +$labels['objectdiffnotavailable'] = 'Kein vergleich für die ausgewählten Stände möglich'; +$labels['objectrestoresuccess'] = 'Stand $rev erfolgreich wiederhergestellt'; +$labels['objectrestoreerror'] = 'Der alte Stand konnte nicht wiederhergestellt werden'; +$labels['arialabelcalendarview'] = 'Kalenderansicht'; +$labels['arialabeleventresources'] = 'Liste der Hilfsmittel des Termins'; +$labels['arialabelresourceselection'] = 'Verfügbare Hilfsmittel'; ?> diff --git a/plugins/kolab_2fa/localization/de.inc b/plugins/kolab_2fa/localization/de.inc new file mode 100644 index 00000000..814c0777 --- /dev/null +++ b/plugins/kolab_2fa/localization/de.inc @@ -0,0 +1,16 @@ +
Um ein Gerät zu registrieren, bitte zuerst nach der Anleitung von dieser Seite mit dem Server verbinden. Anschließend sollte das Gerät für die Konfiguration hier zur Verfügung stehen.'; +$labels['savingdata'] = 'Daten werden gespeichert...'; +$labels['savingerror'] = 'Fehler beim Speichern der Konfiguration'; +$labels['notsupported'] = 'Ihr Server unterstützt keine Activesync-Konfiguration'; +$labels['devicedeleteconfirm'] = 'Wollen Sie wirklich alle Einstellungen für dieses Gerät löschen?'; +$labels['successfullydeleted'] = 'Die Geräteinstellungen wurden erfolgreich gelöscht'; +$labels['devicenotfound'] = 'Es kann nicht auf die Gerätekonfiguration zugegriffen werden.'; +$labels['devicetype'] = 'Gerätetyp'; +$labels['acsversion'] = 'Protokollversion'; +$labels['useragent'] = 'User Agent'; +$labels['friendlyname'] = 'Lesbarer Name'; +$labels['os'] = 'Betriebssystem'; +$labels['oslanguage'] = 'Betriebssystemsprache'; +$labels['phonenumber'] = 'Telefonnummer'; +$labels['arialabeldeviceframe'] = 'Formular für die Einstellungen zur Gerätesynchronisation'; +?> diff --git a/plugins/kolab_activesync/localization/de_DE.inc b/plugins/kolab_activesync/localization/de_DE.inc index 4e422a00..07de616c 100644 --- a/plugins/kolab_activesync/localization/de_DE.inc +++ b/plugins/kolab_activesync/localization/de_DE.inc @@ -1,33 +1,10 @@
Um ein Gerät zu registrieren, bitte zuerst nach der Anleitung von dieser Seite mit dem Server verbinden. Anschließend sollte das Gerät für die Konfiguration hier zur Verfügung stehen.'; $labels['savingdata'] = 'Daten werden gespeichert...'; -$labels['savingerror'] = 'Fehler beim Speichern der Konfiguration'; -$labels['notsupported'] = 'Ihr Server unterstützt keine Activesync-Konfiguration'; -$labels['devicedeleteconfirm'] = 'Wollen Sie wirklich alle Einstellungen für dieses Gerät löschen?'; -$labels['successfullydeleted'] = 'Die Geräteinstellungen wurden erfolgreich gelöscht'; -$labels['devicenotfound'] = 'Es kann nicht auf die Gerätekonfiguration zugegriffen werden.'; -$labels['devicetype'] = 'Gerätetyp'; -$labels['acsversion'] = 'Protokollversion'; -$labels['useragent'] = 'User Agent'; -$labels['friendlyname'] = 'Lesbarer Name'; -$labels['os'] = 'Betriebssystem'; -$labels['oslanguage'] = 'Betriebssystemsprache'; $labels['phonenumber'] = 'Telefonnummer'; -$labels['arialabeldeviceframe'] = 'Formular für die Einstellungen zur Gerätesynchronisation'; ?> diff --git a/plugins/kolab_addressbook/localization/de.inc b/plugins/kolab_addressbook/localization/de.inc new file mode 100644 index 00000000..51f0d770 --- /dev/null +++ b/plugins/kolab_addressbook/localization/de.inc @@ -0,0 +1,66 @@ +CardDAV-Klienten kopieren, um dasAdressbuch mit einem Computer oder mobilen Gerät zu synchronisieren.'; +$labels['addressbookprio'] = 'Reihenfolge der Adressbücher'; +$labels['personalfirst'] = 'Private(s) Adressbuch/Adressbücher zuerst'; +$labels['globalfirst'] = 'Globale(s) Adressbuch/Adressbücher zuerst'; +$labels['personalonly'] = 'Nur persönliche(s) Adressbuch/Adressbücher'; +$labels['globalonly'] = 'Nur globale(s) Adressbuch/Adressbücher'; +$labels['searchterms'] = 'Suchbegriffe'; +$labels['listsearchresults'] = 'Zusätzliche Adressbücher'; +$labels['foldersearchform'] = 'Suchformular für Adressbuch'; +$labels['foldersubscribe'] = 'Permanent anzeigen'; +$labels['nraddressbooksfound'] = '$nr Adressbücher gefunden'; +$labels['noaddressbooksfound'] = 'Keine Adressbücher gefunden'; +$labels['showhistory'] = 'Historie anzeigen'; +$labels['objectchangelog'] = 'Änderungshistorie'; +$labels['objectdiff'] = 'Änderungen aus $rev1 nach $rev2'; +$labels['revisionrestoreconfirm'] = 'Wollen Sie wirklich die Version $rev dieses Kontakt wiederherstellen? Diese Aktion wird die aktuelle Kopie mit der älteren Version ersetzen.'; +$labels['objectnotfound'] = 'Fehler beim Laden der Addressedaten'; +$labels['objectchangelognotavailable'] = 'Änderungshistorie ist nicht verfügbar für diesen Kontakt'; +$labels['objectdiffnotavailable'] = 'Vergleich für die gewählten Versionen nicht möglich'; +$labels['objectrestoresuccess'] = 'Revision $rev erfolgreich wiederhergestellt'; +$labels['objectrestoreerror'] = 'Fehler beim Wiederherstellen der alten Revision'; +$messages['bookdeleteconfirm'] = 'Soll das gewählte Adressbuch und alle Kontakte darin wirklich gelöscht werden?'; +$messages['bookdeleting'] = 'Adressbuch wird gelöscht...'; +$messages['booksaving'] = 'Adressbuch wird gespeichert...'; +$messages['bookdeleted'] = 'Adressbuch erfolgreich gelöscht.'; +$messages['bookupdated'] = 'Adressbuch erfolgreich aktualisiert.'; +$messages['bookcreated'] = 'Adressbuch erfolgreich angelegt.'; +$messages['bookdeleteerror'] = 'Fehler beim Löschen des Adressbuchs.'; +$messages['bookupdateerror'] = 'Fehler beim Aktualisieren des Adressbuchs.'; +$messages['bookcreateerror'] = 'Fehler beim Anlegen des Adressbuchs.'; +$messages['nobooknamewarning'] = 'Bitte den Namen des Adressbuchs angeben.'; +$messages['noemailnamewarning'] = 'Bitte E-Mail-Adresse oder Namen des Kontakts angeben.'; +?> diff --git a/plugins/kolab_addressbook/localization/de_DE.inc b/plugins/kolab_addressbook/localization/de_DE.inc index 51f0d770..0cbc4665 100644 --- a/plugins/kolab_addressbook/localization/de_DE.inc +++ b/plugins/kolab_addressbook/localization/de_DE.inc @@ -6,61 +6,43 @@ * * For translation see https://www.transifex.com/projects/p/kolab/resource/kolab_addressbook/ */ -$labels['initials'] = 'Initialen'; -$labels['profession'] = 'Berufsbezeichnung'; -$labels['officelocation'] = 'Büro Adresse'; +$labels['initials'] = 'Initialien'; +$labels['profession'] = 'Beruf'; $labels['children'] = 'Kinder'; -$labels['pgppublickey'] = 'PGP-Schlüssel'; -$labels['pkcs7publickey'] = 'S/MIME-Schlüssel'; -$labels['freebusyurl'] = 'Frei/Belegt URL'; -$labels['typebusiness'] = 'Dienstlich'; -$labels['typebusinessfax'] = 'Dienst'; +$labels['freebusyurl'] = 'Frei/Beschäftigt-URL'; +$labels['typebusiness'] = 'Geschäftlich'; +$labels['typebusinessfax'] = 'Fax geschäftlich'; $labels['typecompany'] = 'Firma'; -$labels['typeprimary'] = 'Primär'; -$labels['typetelex'] = 'Fernschreiber'; -$labels['typeradio'] = 'Funktelefon'; +$labels['typeprimary'] = 'Bevorzugt'; $labels['typeisdn'] = 'ISDN'; -$labels['typettytdd'] = 'Schreibtelefon'; -$labels['typecallback'] = 'Rückruf'; $labels['settings'] = 'Einstellungen'; $labels['bookcreate'] = 'Adressbuch anlegen'; $labels['bookedit'] = 'Adressbuch bearbeiten'; $labels['bookdelete'] = 'Adressbuch löschen'; -$labels['bookremove'] = 'Von der Liste entfernen'; +$labels['bookremove'] = 'Aus Liste entfernen'; $labels['bookproperties'] = 'Eigenschaften des Adressbuchs'; -$labels['bookname'] = 'Name des Buches'; -$labels['parentbook'] = 'Übergeordnetes Buch'; -$labels['bookshowurl'] = 'CardDAV URL anzeigen'; -$labels['carddavurldescription'] = 'Diese Adresse in einen CardDAV-Klienten kopieren, um dasAdressbuch mit einem Computer oder mobilen Gerät zu synchronisieren.'; -$labels['addressbookprio'] = 'Reihenfolge der Adressbücher'; -$labels['personalfirst'] = 'Private(s) Adressbuch/Adressbücher zuerst'; -$labels['globalfirst'] = 'Globale(s) Adressbuch/Adressbücher zuerst'; -$labels['personalonly'] = 'Nur persönliche(s) Adressbuch/Adressbücher'; -$labels['globalonly'] = 'Nur globale(s) Adressbuch/Adressbücher'; +$labels['bookshowurl'] = 'Zeige CardDAV-URL'; +$labels['carddavurldescription'] = 'Kopieren Sie diese Adresse in eine CardDAV-Client-Anwendung um dieses Adressbuch mit Ihrem Computer oder Mobilgerät zu synchronisieren.'; $labels['searchterms'] = 'Suchbegriffe'; $labels['listsearchresults'] = 'Zusätzliche Adressbücher'; -$labels['foldersearchform'] = 'Suchformular für Adressbuch'; -$labels['foldersubscribe'] = 'Permanent anzeigen'; $labels['nraddressbooksfound'] = '$nr Adressbücher gefunden'; $labels['noaddressbooksfound'] = 'Keine Adressbücher gefunden'; $labels['showhistory'] = 'Historie anzeigen'; $labels['objectchangelog'] = 'Änderungshistorie'; -$labels['objectdiff'] = 'Änderungen aus $rev1 nach $rev2'; -$labels['revisionrestoreconfirm'] = 'Wollen Sie wirklich die Version $rev dieses Kontakt wiederherstellen? Diese Aktion wird die aktuelle Kopie mit der älteren Version ersetzen.'; -$labels['objectnotfound'] = 'Fehler beim Laden der Addressedaten'; -$labels['objectchangelognotavailable'] = 'Änderungshistorie ist nicht verfügbar für diesen Kontakt'; -$labels['objectdiffnotavailable'] = 'Vergleich für die gewählten Versionen nicht möglich'; -$labels['objectrestoresuccess'] = 'Revision $rev erfolgreich wiederhergestellt'; -$labels['objectrestoreerror'] = 'Fehler beim Wiederherstellen der alten Revision'; -$messages['bookdeleteconfirm'] = 'Soll das gewählte Adressbuch und alle Kontakte darin wirklich gelöscht werden?'; +$labels['objectdiff'] = 'Änderungen seit $rev1 bis $rev2'; +$labels['revisionrestoreconfirm'] = 'Möchten Sie wirklich den Stand $rev für diesen Kontakt wiederherstellen? Dadurch wird der aktuelle Kontakt durch die alte Version ersetzt.'; +$labels['objectchangelognotavailable'] = 'Für diesen Kontakt ist keine Änderungshistorie verfügbar'; +$labels['objectdiffnotavailable'] = 'Kein vergleich für die ausgewählten Stände möglich'; +$labels['objectrestoresuccess'] = 'Stand $rev erfolgreich wiederhergestellt'; +$labels['objectrestoreerror'] = 'Der alte Stand konnte nicht wiederhergestellt werden'; +$messages['bookdeleteconfirm'] = 'Möchten Sie das ausgewählte Adressbuch und alle darin enthaltenen Kontakte wirklich löschen?'; $messages['bookdeleting'] = 'Adressbuch wird gelöscht...'; $messages['booksaving'] = 'Adressbuch wird gespeichert...'; $messages['bookdeleted'] = 'Adressbuch erfolgreich gelöscht.'; $messages['bookupdated'] = 'Adressbuch erfolgreich aktualisiert.'; $messages['bookcreated'] = 'Adressbuch erfolgreich angelegt.'; -$messages['bookdeleteerror'] = 'Fehler beim Löschen des Adressbuchs.'; -$messages['bookupdateerror'] = 'Fehler beim Aktualisieren des Adressbuchs.'; -$messages['bookcreateerror'] = 'Fehler beim Anlegen des Adressbuchs.'; -$messages['nobooknamewarning'] = 'Bitte den Namen des Adressbuchs angeben.'; -$messages['noemailnamewarning'] = 'Bitte E-Mail-Adresse oder Namen des Kontakts angeben.'; +$messages['bookdeleteerror'] = 'Beim Löschen des Adressbuchs ist ein Fehler aufgetreten.'; +$messages['bookupdateerror'] = 'Bei der Aktualisierung des Adressbuchs ist ein Fehler aufgetreten.'; +$messages['bookcreateerror'] = 'Beim Anlegen des Adressbuchs ist ein Fehler aufgetreten.'; +$messages['nobooknamewarning'] = 'Bitte geben Sie den Namen des Adressbuchs ein.'; ?> diff --git a/plugins/kolab_auth/localization/de.inc b/plugins/kolab_auth/localization/de.inc new file mode 100644 index 00000000..3918e6e3 --- /dev/null +++ b/plugins/kolab_auth/localization/de.inc @@ -0,0 +1,11 @@ + diff --git a/plugins/kolab_auth/localization/de_DE.inc b/plugins/kolab_auth/localization/de_DE.inc index 3918e6e3..8875c6bc 100644 --- a/plugins/kolab_auth/localization/de_DE.inc +++ b/plugins/kolab_auth/localization/de_DE.inc @@ -7,5 +7,5 @@ * For translation see https://www.transifex.com/projects/p/kolab/resource/kolab_auth/ */ $labels['loginas'] = 'Anmelden als'; -$labels['loginasnotallowed'] = 'Keine Privilegien zum Anmelden als $user'; +$labels['loginasnotallowed'] = 'Keine Berechtigung sich als $user anzumelden'; ?> diff --git a/plugins/kolab_chat/localization/de_DE.inc b/plugins/kolab_chat/localization/de.inc similarity index 100% rename from plugins/kolab_chat/localization/de_DE.inc rename to plugins/kolab_chat/localization/de.inc diff --git a/plugins/kolab_delegation/localization/de.inc b/plugins/kolab_delegation/localization/de.inc new file mode 100644 index 00000000..8c99210b --- /dev/null +++ b/plugins/kolab_delegation/localization/de.inc @@ -0,0 +1,36 @@ + diff --git a/plugins/kolab_delegation/localization/de_DE.inc b/plugins/kolab_delegation/localization/de_DE.inc index 8c99210b..a6789061 100644 --- a/plugins/kolab_delegation/localization/de_DE.inc +++ b/plugins/kolab_delegation/localization/de_DE.inc @@ -6,10 +6,7 @@ * * For translation see https://www.transifex.com/projects/p/kolab/resource/kolab_delegation/ */ -$labels['tabtitle'] = 'Vertretung'; -$labels['delegationtitle'] = 'Verwalte Vertreter'; $labels['delegates'] = 'Vertreter'; -$labels['delegate'] = 'Vertreter'; $labels['mail'] = 'E-Mail'; $labels['contact'] = 'Kontakte'; $labels['event'] = 'Kalender'; @@ -17,20 +14,5 @@ $labels['task'] = 'Aufgaben'; $labels['note'] = 'Notizen'; $labels['yes'] = 'Ja'; $labels['no'] = 'Nein'; -$labels['read'] = 'Schreibgeschützt'; -$labels['write'] = 'Schreiben'; -$labels['adddelegate'] = 'Vertreter hinzufügen'; -$labels['deletedelegate'] = 'Vertreter löschen'; -$labels['savingdata'] = 'Speichere Daten...'; -$labels['delegatedeleteconfirm'] = 'Willst du wirklich diesen Vertreter löschen?'; -$labels['delegateremoveacl'] = 'Entferne Zugriffsberechtigungen auf den für diesen Benutzer zugewiesenen Ordnern.'; -$labels['deleteconfirm'] = 'Bestätigung'; -$labels['deletesuccess'] = 'Der Vertreter wurde erfolgreich entfernt'; -$labels['deleteerror'] = 'Konnte Vertreter nicht entfernen.'; -$labels['updatesuccess'] = 'Der Vertreter wurde erfolgreich aktualisiert.'; -$labels['updateerror'] = 'Konnte Verteter nicht aktualisieren'; -$labels['createsuccess'] = 'Der Vertreter wurde erfolgreich hinzugefügt'; -$labels['createerror'] = 'Konnte Vertreter nicht hinzufügen.'; -$labels['arialabeldelegatedelete'] = 'Vertreter Löschen Dialog'; -$labels['arialabeldelegateform'] = 'Verterter Eigenschaften Maske'; +$labels['savingdata'] = 'Daten werden gespeichert...'; ?> diff --git a/plugins/kolab_files/localization/de.inc b/plugins/kolab_files/localization/de.inc new file mode 100644 index 00000000..4b5ce4ab --- /dev/null +++ b/plugins/kolab_files/localization/de.inc @@ -0,0 +1,152 @@ +$file überschreiben.'; +$labels['editfiledialog'] = 'Bearbeitungsaktion bestätigen'; +$labels['newsession'] = 'Neue Sitzung erstellen'; +$labels['ownedsession'] = 'Vorhandene Sitzung vortsetzen'; +$labels['invitedsession'] = 'Sitzung des Benutzers $user beitreten'; +$labels['editfilerotitle'] = 'Schreibgeschützte Datei'; +$labels['select'] = 'Auswählen'; +$labels['terminatesession'] = 'Sitzung beenden'; +$labels['sessionterminatedtitle'] = 'Sitzung beendet'; +$labels['terminate'] = 'Beenden'; +$labels['sessionterminating'] = 'Sitzung wird beendet …'; +$labels['participant'] = 'Teilnehmer'; +$labels['status'] = 'Status'; +$labels['addparticipant'] = 'Hinzufügen'; +$labels['delparticipant'] = 'Teilnehmer entfernen'; +$labels['invitationtextlabel'] = 'Kommentar zur Einladungs-/Benachrichtigungsnachricht'; +$labels['statusorganizer'] = 'Organisator'; +$labels['statusinvited'] = 'Eingeladen'; +$labels['statusaccepted'] = 'Angenommen'; +$labels['statusdeclined'] = 'Abgelehnt'; +$labels['statusrequested'] = 'Angefordert'; +$labels['documentinviting'] = 'Teilnehmer wird/werden eingeladen …'; +$labels['documentcancelling'] = 'Teilnehmer wird/werden entfernt …'; +$labels['removeparticipant'] = 'Entfernen'; +$labels['sessiondialog'] = 'Dokumentbearbeitungssitzung'; +$labels['more'] = 'Mehr.'; +$labels['accept'] = 'Annehmen'; +$labels['join'] = 'Der Sitzung beitreten'; +$labels['decline'] = 'Ablehnen'; +$labels['owner'] = 'Eigentümer'; +$labels['when'] = 'Wenn'; +$labels['file'] = 'Datei'; +$labels['comment'] = 'Kommentar'; +$labels['open'] = 'Öffnen'; +$labels['invitationtitle'] = 'Einladung für $file'; +$labels['invitationaccepting'] = 'Eine Einladung wird angenommen …'; +$labels['invitationdeclining'] = 'Eine Einladung wird abgelehnt …'; +$labels['invitationrequesting'] = 'Einladung wird angefordert …'; +$labels['storepasswords'] = 'Passwort merken'; +$labels['storepasswordsdesc'] = 'Gespeicherte Passwörter werden verschlüsselt. Aktivieren Sie dies, wenn Sie nicht bei jedem Login nach dem Passwort gefragt werden möchten oder wenn dieser Speicher via WebDAV verfügbar sein soll.'; +$labels['arialabelsearchform'] = 'Suchformular für Dateien'; +$labels['arialabelquicksearchbox'] = 'Sucheingabe'; +$labels['arialabellistoptions'] = 'Dateilisten Optionen'; +$labels['arialabelfolderoptions'] = 'Ordneraktionen'; +$labels['arialabelfileeditform'] = 'Dateibearbeitenformular'; +$labels['arialabelfilecreateform'] = 'Dateierstellenformular'; +$labels['arialabelfilelist'] = 'Dateiliste'; +$labels['arialabelfoldercreateform'] = 'Ordnererstellenformular'; +$labels['arialabelfoldereditform'] = 'Ordnerbearbeitenformular'; +$labels['arialabelfoldermountform'] = 'Externer-Speicherformular'; +$labels['arialabelfolderauthform'] = 'Legitimierungsformular des externen Speichers'; +$labels['arialabelfolderlist'] = 'Ordner-/Sammelauswahl'; +$labels['arialabelfileselectdialog'] = 'Dateiauswahldialog'; +$labels['arialabelattachmentoptions'] = 'Anhängespeichernoptionen'; +$labels['arialabelfilesavedialog'] = 'Datei(en)speicherndialog'; +$labels['arialabelfileprops'] = 'Dateieigenschaften'; +$labels['arialabelfilecontent'] = 'Dateiinhalt'; +$labels['arialabelfileeditdialog'] = 'Dateibearbeitungsdialog'; +$labels['arialabelfilesessiondialog'] = 'Dokumentbearbeitungssitzung'; +$labels['type.plain'] = 'Klartextdokument'; +$labels['type.vndoasisopendocumenttext'] = 'Textdokument (ODF)'; +$labels['type.html'] = 'HTML-Dokument'; diff --git a/plugins/kolab_files/localization/de_DE.inc b/plugins/kolab_files/localization/de_DE.inc index 4b5ce4ab..90176ef3 100644 --- a/plugins/kolab_files/localization/de_DE.inc +++ b/plugins/kolab_files/localization/de_DE.inc @@ -7,146 +7,28 @@ * For translation see https://www.transifex.com/projects/p/kolab/resource/kolab_files/ */ $labels['files'] = 'Dateien'; -$labels['filepreview'] = 'Dateivorschau'; -$labels['saveall'] = 'Alles in der Cloud speichern …'; -$labels['saveto'] = 'In der Cloud speichern …'; -$labels['saveas'] = 'Speichern als:'; $labels['create'] = 'Erstellen'; $labels['save'] = 'Speichern'; $labels['cancel'] = 'Abbrechen'; -$labels['fromcloud'] = 'Aus der Cloud …'; -$labels['selectfiles'] = 'Datei(en) zum Anhängen auswählen …'; -$labels['attachsel'] = 'Ausgewählte anhängen'; -$labels['foldercreate'] = 'Ordner erstellen'; -$labels['folderedit'] = 'Ordner ändern'; -$labels['folderrename'] = 'Ordner umbenennen'; -$labels['foldermount'] = 'Speicher hinzufügen'; -$labels['folderdelete'] = 'Ordner löschen'; -$labels['folderoptions'] = 'Ordneroptionen'; -$labels['folderinside'] = 'Erstellen in'; -$labels['foldername'] = 'Ordnername'; +$labels['addfolder'] = 'Ordner hinzufügen'; +$labels['foldermount'] = 'Speicherplatz hinzufügen'; $labels['name'] = 'Name'; -$labels['mtime'] = 'Geändert'; $labels['type'] = 'Typ'; -$labels['upload'] = 'Hochladen'; -$labels['uploadfile'] = 'Datei(en) hochladen'; -$labels['get'] = 'Herunterladen'; -$labels['getfile'] = 'Datei herunterladen'; -$labels['view'] = 'Ansehen'; -$labels['viewfile'] = 'Datei ansehen'; -$labels['rename'] = 'Umbenennen'; -$labels['deletefile'] = 'Datei(en) löschen'; $labels['edit'] = 'Bearbeiten'; -$labels['editfile'] = 'Datei bearbeiten'; $labels['save'] = 'Speichern'; -$labels['savefile'] = 'Datei speichern'; -$labels['printfile'] = 'Datei drucken'; -$labels['renamefile'] = 'Datei umbenennen'; -$labels['createfile'] = 'Datei erstellen'; -$labels['createandedit'] = 'Erstellen und Bearbeiten'; -$labels['copyfile'] = 'Datei kopieren'; -$labels['copyandedit'] = 'Kopieren und Bearbeiten'; -$labels['documenttitle'] = 'Titel:'; $labels['close'] = 'Schließen'; $labels['submit'] = 'Absenden'; $labels['confirmpassword'] = 'Passwort bestätigen'; -$labels['collection_audio'] = 'Audio'; -$labels['collection_video'] = 'Video'; -$labels['collection_image'] = 'Bilder'; -$labels['collection_document'] = 'Dokumente'; -$labels['sessions'] = 'Sitzungen'; -$labels['uploading'] = 'Datei(en) wird/werden hochgeladen …'; -$labels['attaching'] = 'Datei(en) wird/werden angehängt …'; -$labels['authenticating'] = 'Legitimierung wird durchgeführt …'; -$labels['foldercreating'] = 'Ordner wird erstellt …'; -$labels['folderupdating'] = 'Ordner wird aktualisiert …'; -$labels['foldermounting'] = 'Externer Speicher wird hinzugefügt …'; -$labels['folderdeleting'] = 'Ordner werden gelöscht …'; -$labels['folderdeleteconfirm'] = 'Sind Sie sicher, dass Sie den gewählten Ordner löschen möchten?'; -$labels['folderdeletenotice'] = 'Ordner erfolgreich gelöscht.'; -$labels['folderupdatenotice'] = 'Ordner erfolgreich aktualisiert.'; -$labels['foldercreatenotice'] = 'Ordner erfolgreich erstellt.'; -$labels['foldermountnotice'] = 'Speicher erfolgreich hinzugefügt.'; -$labels['folderauthtitle'] = 'Anmelden in $title'; -$labels['saveallnotice'] = '$n Datei(en) erfolgreich gespeichert.'; -$labels['saveallerror'] = 'Speichern von $n Datei(en) fehlgeschlagen.'; -$labels['attacherror'] = 'Anhängen von Datei(en) aus der Cloud fehlgeschlagen.'; -$labels['fileupdating'] = 'Datei wird aktualisiert …'; -$labels['filecreating'] = 'Datei wird erstellt …'; -$labels['filemoving'] = 'Datei(en) wird/werden verschoben …'; -$labels['filecopying'] = 'Datei(en) wird/werden kopiert …'; -$labels['filedeleting'] = 'Datei(en) wird/werden gelöscht …'; -$labels['filedeleteconfirm'] = 'Sind Sie sicher, dass Sie die gewählten Dateien löschen möchten?'; -$labels['filedeletenotice'] = 'Datei(en) erfolgreich gelöscht.'; -$labels['filemovenotice'] = 'Datei(en) erfolgreich verschoben.'; -$labels['filecopynotice'] = 'Datei(en) erfolgreich kopiert.'; -$labels['uploadsizeerror'] = 'Maximale Dateigröße ($size) überschritten!'; -$labels['listpermanent'] = 'Dauerhaft anzeigen'; -$labels['additionalfolders'] = 'Zusätzliche Ordner'; -$labels['allfolders'] = 'in allen Ordnern suchen'; -$labels['fileskip'] = 'Überspringen'; -$labels['fileskipall'] = 'Alle überspringen'; -$labels['fileoverwrite'] = 'Überschreiben'; -$labels['fileoverwriteall'] = 'Alle überschreiben'; -$labels['filemoveconfirm'] = 'Diese Aktion wird die Zieldatei $file überschreiben.'; -$labels['editfiledialog'] = 'Bearbeitungsaktion bestätigen'; -$labels['newsession'] = 'Neue Sitzung erstellen'; -$labels['ownedsession'] = 'Vorhandene Sitzung vortsetzen'; -$labels['invitedsession'] = 'Sitzung des Benutzers $user beitreten'; -$labels['editfilerotitle'] = 'Schreibgeschützte Datei'; +$labels['foldermounting'] = 'Externe Speicherplatz hinzufügen'; +$labels['foldermountnotice'] = 'Speicherplatz erfolgreich angelegt.'; +$labels['additionalfolders'] = 'Zusätzliche Ordneren'; $labels['select'] = 'Auswählen'; -$labels['terminatesession'] = 'Sitzung beenden'; -$labels['sessionterminatedtitle'] = 'Sitzung beendet'; -$labels['terminate'] = 'Beenden'; -$labels['sessionterminating'] = 'Sitzung wird beendet …'; $labels['participant'] = 'Teilnehmer'; $labels['status'] = 'Status'; -$labels['addparticipant'] = 'Hinzufügen'; -$labels['delparticipant'] = 'Teilnehmer entfernen'; -$labels['invitationtextlabel'] = 'Kommentar zur Einladungs-/Benachrichtigungsnachricht'; +$labels['addparticipant'] = 'Teilnehmer hinzufügen'; $labels['statusorganizer'] = 'Organisator'; -$labels['statusinvited'] = 'Eingeladen'; -$labels['statusaccepted'] = 'Angenommen'; +$labels['statusaccepted'] = 'Akzeptiert'; $labels['statusdeclined'] = 'Abgelehnt'; -$labels['statusrequested'] = 'Angefordert'; -$labels['documentinviting'] = 'Teilnehmer wird/werden eingeladen …'; -$labels['documentcancelling'] = 'Teilnehmer wird/werden entfernt …'; $labels['removeparticipant'] = 'Entfernen'; -$labels['sessiondialog'] = 'Dokumentbearbeitungssitzung'; -$labels['more'] = 'Mehr.'; -$labels['accept'] = 'Annehmen'; -$labels['join'] = 'Der Sitzung beitreten'; -$labels['decline'] = 'Ablehnen'; -$labels['owner'] = 'Eigentümer'; -$labels['when'] = 'Wenn'; -$labels['file'] = 'Datei'; +$labels['owner'] = 'Besitzer'; $labels['comment'] = 'Kommentar'; -$labels['open'] = 'Öffnen'; -$labels['invitationtitle'] = 'Einladung für $file'; -$labels['invitationaccepting'] = 'Eine Einladung wird angenommen …'; -$labels['invitationdeclining'] = 'Eine Einladung wird abgelehnt …'; -$labels['invitationrequesting'] = 'Einladung wird angefordert …'; -$labels['storepasswords'] = 'Passwort merken'; -$labels['storepasswordsdesc'] = 'Gespeicherte Passwörter werden verschlüsselt. Aktivieren Sie dies, wenn Sie nicht bei jedem Login nach dem Passwort gefragt werden möchten oder wenn dieser Speicher via WebDAV verfügbar sein soll.'; -$labels['arialabelsearchform'] = 'Suchformular für Dateien'; -$labels['arialabelquicksearchbox'] = 'Sucheingabe'; -$labels['arialabellistoptions'] = 'Dateilisten Optionen'; -$labels['arialabelfolderoptions'] = 'Ordneraktionen'; -$labels['arialabelfileeditform'] = 'Dateibearbeitenformular'; -$labels['arialabelfilecreateform'] = 'Dateierstellenformular'; -$labels['arialabelfilelist'] = 'Dateiliste'; -$labels['arialabelfoldercreateform'] = 'Ordnererstellenformular'; -$labels['arialabelfoldereditform'] = 'Ordnerbearbeitenformular'; -$labels['arialabelfoldermountform'] = 'Externer-Speicherformular'; -$labels['arialabelfolderauthform'] = 'Legitimierungsformular des externen Speichers'; -$labels['arialabelfolderlist'] = 'Ordner-/Sammelauswahl'; -$labels['arialabelfileselectdialog'] = 'Dateiauswahldialog'; -$labels['arialabelattachmentoptions'] = 'Anhängespeichernoptionen'; -$labels['arialabelfilesavedialog'] = 'Datei(en)speicherndialog'; -$labels['arialabelfileprops'] = 'Dateieigenschaften'; -$labels['arialabelfilecontent'] = 'Dateiinhalt'; -$labels['arialabelfileeditdialog'] = 'Dateibearbeitungsdialog'; -$labels['arialabelfilesessiondialog'] = 'Dokumentbearbeitungssitzung'; -$labels['type.plain'] = 'Klartextdokument'; -$labels['type.vndoasisopendocumenttext'] = 'Textdokument (ODF)'; -$labels['type.html'] = 'HTML-Dokument'; diff --git a/plugins/kolab_folders/localization/de.inc b/plugins/kolab_folders/localization/de.inc new file mode 100644 index 00000000..96a85235 --- /dev/null +++ b/plugins/kolab_folders/localization/de.inc @@ -0,0 +1,30 @@ + diff --git a/plugins/kolab_folders/localization/de_DE.inc b/plugins/kolab_folders/localization/de_DE.inc index 96a85235..82470094 100644 --- a/plugins/kolab_folders/localization/de_DE.inc +++ b/plugins/kolab_folders/localization/de_DE.inc @@ -6,7 +6,7 @@ * * For translation see https://www.transifex.com/projects/p/kolab/resource/kolab_folders/ */ -$labels['folderctype'] = 'Inhaltstyp'; +$labels['folderctype'] = 'Art des Inhalts'; $labels['foldertypemail'] = 'E-Mail'; $labels['foldertypeevent'] = 'Kalender'; $labels['foldertypejournal'] = 'Journal'; @@ -15,16 +15,11 @@ $labels['foldertypenote'] = 'Notizen'; $labels['foldertypecontact'] = 'Kontakte'; $labels['foldertypeconfiguration'] = 'Konfiguration'; $labels['foldertypefile'] = 'Dateien'; -$labels['foldertypefreebusy'] = 'Frei/Belegt'; +$labels['foldertypefreebusy'] = 'Frei/Beschäftigt'; $labels['default'] = 'Standard'; -$labels['inbox'] = 'Posteingang'; $labels['drafts'] = 'Entwürfe'; $labels['sentitems'] = 'Gesendet'; -$labels['outbox'] = 'Postausgang'; -$labels['wastebasket'] = 'Mülleimer'; -$labels['junkemail'] = 'Spam'; +$labels['wastebasket'] = 'Papierkorb'; $labels['confidential'] = 'Vertraulich'; $labels['private'] = 'Privat'; -$labels['xdays'] = '$x Tage'; -$messages['defaultfolderexists'] = 'Es gibt bereits einen Standardordner des angegebenen Typs'; ?> diff --git a/plugins/kolab_notes/localization/de.inc b/plugins/kolab_notes/localization/de.inc new file mode 100644 index 00000000..fbf9ef01 --- /dev/null +++ b/plugins/kolab_notes/localization/de.inc @@ -0,0 +1,62 @@ +einzelne Wiederholung einer Serie von Ereignissen'; +$labels['itipfutureoccurrence'] = 'Bezieht sich auf diese and alle zukünftigen Wiederholungen einer Serie von Ereignissen'; +$labels['itipmessagesingleoccurrence'] = 'Diese Nachricht bezieht sich nur auf eine einzelne Wiederholung'; +$labels['itipmessagefutureoccurrence'] = 'Diese Nachricht bezieht sich auf diese und alle zukünftigen Wiederholungen'; +$labels['youhaveaccepted'] = 'Sie haben die Einladung angenommen'; +$labels['youhavetentative'] = 'Sie haben die Einladung mit Vorbehalt angenommen'; +$labels['youhavedeclined'] = 'Sie haben die Einladung abgelehnt'; +$labels['youhavedelegated'] = 'Sie haben diese Einladung abgelehnt'; +$labels['youhavein-process'] = 'Sie arbeiten an dieser Aufgabe'; +$labels['youhavecompleted'] = 'Sie haben diese Aufgabe erledigt'; +$labels['youhaveneeds-action'] = 'Ihre Antwort auf diese Einladung ist noch ausstehend'; +$labels['youhavepreviouslyaccepted'] = 'Sie haben diese Einladung zuvor angenommen'; +$labels['youhavepreviouslytentative'] = 'Sie haben diese Einladung zuvor mit Vorbehalt angenommen'; +$labels['youhavepreviouslydeclined'] = 'Sie haben diese Einladung zuvor abgelehnt'; +$labels['youhavepreviouslydelegated'] = 'Sie haben diese Einladung zuvor delegiert'; +$labels['youhavepreviouslyin-process'] = 'Sie haben diese Aufgabe zuvor als In Bearbeitung gemeldet'; +$labels['youhavepreviouslycompleted'] = 'Sie haben diese Einladung zuvor erledigt'; +$labels['youhavepreviouslyneeds-action'] = 'Ihre Antwort auf diese Einladung ist noch ausstehend'; +$labels['attendeeaccepted'] = 'Teilnehmer hat akzeptiert'; +$labels['attendeetentative'] = 'Teilnehmer hat mit Vorbehalt akzeptiert'; +$labels['attendeedeclined'] = 'Teilnehmer hat abgelehnt'; +$labels['attendeedelegated'] = 'Teilnehmer hat an $delegatedto delegiert'; +$labels['attendeein-process'] = 'Teilnehmer arbeitet an dieser Aufgabe'; +$labels['attendeecompleted'] = 'Teilnehmer hat die Aufgabe erledigt'; +$labels['notanattendee'] = 'Sie sind nicht in der Liste der Teilnehmer aufgeführt'; +$labels['outdatedinvitation'] = 'Diese Einladung wurde durch eine neuere Version ersetzt'; +$labels['importtocalendar'] = 'In Kalender übernehmen'; +$labels['removefromcalendar'] = 'Aus meinem Kalender löschen'; +$labels['updatemycopy'] = 'Meine Kopie aktualisieren'; +$labels['openpreview'] = 'Vorschau öffnen'; +$labels['deleteobjectconfirm'] = 'Möchten Sie dieses Objekt wirklich löschen?'; +$labels['declinedeleteconfirm'] = 'Soll das abgelehnte Objekt ebenfalls aus Ihrem Konto gelöscht werden?'; +$labels['delegateinvitation'] = 'Einladung delegieren'; +$labels['delegateto'] = 'Delegieren an'; +$labels['delegatersvpme'] = 'Informiere mich über Aktualisierungen dieses Termins'; +$labels['delegateinvalidaddress'] = 'Geben Sie eine gültige E-Mail-Adresse für den Delegierten ein'; +$labels['savingdata'] = 'Speichere...'; +$labels['savein'] = 'Speichern in'; +$labels['expandattendeegroup'] = 'Mit Gruppenmitgliedern ersetzen'; +$labels['expandattendeegroupnodata'] = 'Diese Gruppe konnte nicht ersetzt werden. Keine Gruppenmitglieder gefunden.'; +$labels['expandattendeegrouperror'] = 'Diese Gruppe konnte nicht ersetzt werden. Sie hat möglicherweise zuviele Mitglieder.'; +$labels['expandattendeegroupsizelimit'] = 'Die Gruppe hat zuviele Mitglieder und konnte deshalb nicht ersetzt werden.'; diff --git a/plugins/libcalendaring/localization/de_DE.inc b/plugins/libcalendaring/localization/de_DE.inc index 680c2ec4..14f6504c 100644 --- a/plugins/libcalendaring/localization/de_DE.inc +++ b/plugins/libcalendaring/localization/de_DE.inc @@ -7,156 +7,83 @@ * For translation see https://www.transifex.com/projects/p/kolab/resource/libcalendaring/ */ $labels['until'] = 'bis'; -$labels['at'] = 'um'; +$labels['at'] = 'am'; $labels['alarmemail'] = 'E-Mail senden'; -$labels['alarmdisplay'] = 'Nachricht anzeigen'; -$labels['alarmaudio'] = 'Audio abspielen'; +$labels['alarmdisplay'] = 'Zeige Nachricht'; +$labels['alarmaudio'] = 'Klang abspielen'; $labels['alarmdisplayoption'] = 'Nachricht'; $labels['alarmemailoption'] = 'E-Mail'; -$labels['alarmaudiooption'] = 'Audio'; -$labels['alarmat'] = 'um $datetime'; -$labels['trigger@'] = 'genau am'; -$labels['trigger-M'] = 'Minuten davor'; -$labels['trigger-H'] = 'Stunden davor'; -$labels['trigger-D'] = 'Tage davor'; -$labels['trigger+M'] = 'Minuten danach'; -$labels['trigger+H'] = 'Stunden danach'; -$labels['trigger+D'] = 'Tage danach'; -$labels['triggerend-M'] = 'Minuten vor dem Ende'; -$labels['triggerend-H'] = 'Stunden vor dem Ende'; -$labels['triggerend-D'] = 'Tage vor dem Ende'; -$labels['triggerend+M'] = 'Minuten nach dem Ende'; -$labels['triggerend+H'] = 'Stunden nach dem Ende'; -$labels['triggerend+D'] = 'Tage nach dem Ende'; -$labels['trigger0'] = 'um exakt'; +$labels['alarmaudiooption'] = 'Klang'; +$labels['trigger@'] = 'am Datum'; +$labels['trigger-M'] = 'Minuten vor'; +$labels['trigger-H'] = 'Stunden vor'; +$labels['trigger-D'] = 'Tage vor'; +$labels['trigger+M'] = 'Minuten nach'; +$labels['trigger+H'] = 'Stunden nach'; +$labels['trigger+D'] = 'Tage nach'; +$labels['triggerend-M'] = 'Minuten vor Ende'; +$labels['triggerend-H'] = 'Stunden vor Ende'; +$labels['triggerend-D'] = 'Tage vor Ende'; +$labels['triggerend+M'] = 'Minuten nach Ende'; +$labels['triggerend+H'] = 'Stunden nach Ende'; +$labels['triggerend+D'] = 'Tage nach Ende'; +$labels['trigger0'] = 'zur Uhrzeit'; $labels['triggerattime'] = 'zur Startzeit'; -$labels['triggerattimeend'] = 'zur Endzeit'; -$labels['relatedstart'] = 'Beginn'; +$labels['triggerattimeend'] = 'zur Ende-Zeit'; +$labels['relatedstart'] = 'Anfang'; $labels['relatedendevent'] = 'Ende'; -$labels['relatedendtask'] = 'Fällig'; +$labels['relatedendtask'] = 'Fälligkeitszeit'; $labels['addalarm'] = 'Erinnerung hinzufügen'; $labels['removealarm'] = 'Erinnerung entfernen'; -$labels['alarmtitle'] = 'Anstehende Termine'; -$labels['dismissall'] = 'Alle ignorieren'; -$labels['dismiss'] = 'Ignorieren'; -$labels['snooze'] = 'Später erinnern'; -$labels['repeatinmin'] = 'Wiederholung in $min Minuten'; -$labels['repeatinhr'] = 'Wiederholung in 1 Stunde'; -$labels['repeatinhrs'] = 'Wiederholung in $hrs Stunden'; -$labels['repeattomorrow'] = 'Wiederholung morgen'; -$labels['repeatinweek'] = 'Wiederholung in einer Woche'; -$labels['showmore'] = 'Mehr anzeigen...'; +$labels['alarmtitle'] = 'anstehende Ereignisse'; +$labels['dismissall'] = 'alle absagen'; +$labels['dismiss'] = 'Verwerfen'; +$labels['repeatinmin'] = 'In $min Minuten wiederholen'; +$labels['repeatinhr'] = 'In 1 Stunde wiederholen'; +$labels['repeatinhrs'] = 'In $hrs Stunden wiederholen'; +$labels['repeattomorrow'] = 'morgen wiederholen'; +$labels['repeatinweek'] = 'In einer Woche wiederholen'; +$labels['showmore'] = 'Zeige mehr...'; $labels['recurring'] = 'Wiederholungen'; -$labels['frequency'] = 'Wiederholung'; -$labels['never'] = 'nie'; +$labels['frequency'] = 'Wiederholen'; +$labels['never'] = 'niemals'; $labels['daily'] = 'täglich'; $labels['weekly'] = 'wöchentlich'; $labels['monthly'] = 'monatlich'; $labels['yearly'] = 'jährlich'; -$labels['rdate'] = 'genau am'; -$labels['every'] = 'Alle'; +$labels['rdate'] = 'am Datum'; +$labels['every'] = 'Jede(n)/Alle'; $labels['days'] = 'Tag(e)'; $labels['weeks'] = 'Woche(n)'; $labels['months'] = 'Monat(e)'; -$labels['years'] = 'Jahre(e) im:'; +$labels['years'] = 'Jahr(e)'; $labels['bydates'] = 'Am'; $labels['bydays'] = 'Am'; $labels['bymonths'] = 'Am'; -$labels['untildate'] = 'am'; -$labels['each'] = 'Jeden'; +$labels['each'] = 'Jede/n einzelne/n'; $labels['onevery'] = 'An jedem'; -$labels['onsamedate'] = 'Am gleichen Tag'; -$labels['forever'] = 'unendlich'; +$labels['forever'] = 'fürimmer'; $labels['recurrencend'] = 'bis'; -$labels['untilenddate'] = 'bis am'; -$labels['forntimes'] = '$nr Wiederholungen'; // old +$labels['untilenddate'] = 'bis zum Datum'; +$labels['forntimes'] = '$nr mal'; // old $labels['first'] = 'erster'; $labels['second'] = 'zweiter'; $labels['third'] = 'dritter'; -$labels['fourth'] = 'vierter'; -$labels['last'] = 'letzter'; -$labels['dayofmonth'] = 'Tag des Montats'; -$labels['addrdate'] = 'Datum hinzufügen'; -$labels['except'] = 'ausser'; -$labels['statusorganizer'] = 'Organisator'; +$labels['fourth'] = 'vierte'; +$labels['last'] = 'letzte'; +$labels['dayofmonth'] = 'Tag des Monats'; +$labels['addrdate'] = 'Wiederholungsdatum hinzufügen'; +$labels['except'] = 'außer'; +$labels['statusorganizer'] = 'Veranstalter'; $labels['statusaccepted'] = 'Akzeptiert'; $labels['statustentative'] = 'Mit Vorbehalt'; $labels['statusdeclined'] = 'Abgelehnt'; $labels['statusdelegated'] = 'Delegiert'; -$labels['statusneeds-action'] = 'Braucht Aktion'; +$labels['statusneeds-action'] = 'Bearbeitung erforderlich'; $labels['statusunknown'] = 'Unbekannt'; $labels['statuscompleted'] = 'Abgeschlossen'; -$labels['statusin-process'] = 'In Bearbeitung'; -$labels['itipinvitation'] = 'Einladung zu'; -$labels['itipupdate'] = 'Aktialisiert:'; -$labels['itipcancellation'] = 'Abgesagt:'; -$labels['itipreply'] = 'Antwort zu'; -$labels['itipaccepted'] = 'Akzeptieren'; -$labels['itiptentative'] = 'Mit Vorbehalt'; -$labels['itipdeclined'] = 'Ablehnen'; -$labels['itipdelegated'] = 'Delegieren'; -$labels['itipneeds-action'] = 'Aufschieben'; -$labels['itipcomment'] = 'Ihre Antwort'; -$labels['itipeditresponse'] = 'Antwort eingeben'; -$labels['itipsendercomment'] = 'Kommentar des Absenders:'; -$labels['itipsuppressreply'] = 'Keine Antwort senden'; -$labels['itipobjectnotfound'] = 'Das Objekt auf welches sich diese Nachricht bezieht, wurde in Ihrem Konto nicht gefunden.'; -$labels['itipsubjectaccepted'] = 'Einladung zu "$title" wurde von $name angenommen'; -$labels['itipsubjecttentative'] = 'Einladung zu "$title" wurde von $name mit Vorbehalt angenommen'; -$labels['itipsubjectdeclined'] = 'Einladung zu "$title" wurde von $name abgelehnt'; -$labels['itipsubjectin-process'] = '"$title" ist nun in Bearbeitung von $name'; -$labels['itipsubjectcompleted'] = '"$title" wurde vom $name fertiggestellt'; -$labels['itipsubjectcancel'] = 'Ihre Teilnahme in "$title" wurde aufgehoben'; -$labels['itipsubjectdelegated'] = '"$title" wurde durch $name delegiert'; -$labels['itipsubjectdelegatedto'] = '"$title" wurde durch $name an Sie delegiert'; -$labels['itipnewattendee'] = 'Dies ist eine Antwort von einem neuen Teilnehmer'; -$labels['updateattendeestatus'] = 'Teilnehmerstatus aktualisieren'; -$labels['acceptinvitation'] = 'Möchten Sie die Einladung zu diesem Termin annehmen?'; +$labels['acceptinvitation'] = 'Nehmen Sie diese Einladung an?'; $labels['acceptattendee'] = 'Teilnehmer akzeptieren'; $labels['declineattendee'] = 'Teilnehmer ablehnen'; -$labels['declineattendeeconfirm'] = 'Nachricht an den abgelehnten Teilnehmer verfassen (optional):'; -$labels['rsvpmodeall'] = 'Die gesamte Reihe'; -$labels['rsvpmodecurrent'] = 'Nur dieses Ereignis'; -$labels['rsvpmodefuture'] = 'Dieses und zukünftige Ereignisse'; -$labels['itipsingleoccurrence'] = 'Dieses ist eine einzelne Wiederholung einer Serie von Ereignissen'; -$labels['itipfutureoccurrence'] = 'Bezieht sich auf diese and alle zukünftigen Wiederholungen einer Serie von Ereignissen'; -$labels['itipmessagesingleoccurrence'] = 'Diese Nachricht bezieht sich nur auf eine einzelne Wiederholung'; -$labels['itipmessagefutureoccurrence'] = 'Diese Nachricht bezieht sich auf diese und alle zukünftigen Wiederholungen'; -$labels['youhaveaccepted'] = 'Sie haben die Einladung angenommen'; -$labels['youhavetentative'] = 'Sie haben die Einladung mit Vorbehalt angenommen'; -$labels['youhavedeclined'] = 'Sie haben die Einladung abgelehnt'; -$labels['youhavedelegated'] = 'Sie haben diese Einladung abgelehnt'; -$labels['youhavein-process'] = 'Sie arbeiten an dieser Aufgabe'; -$labels['youhavecompleted'] = 'Sie haben diese Aufgabe erledigt'; -$labels['youhaveneeds-action'] = 'Ihre Antwort auf diese Einladung ist noch ausstehend'; -$labels['youhavepreviouslyaccepted'] = 'Sie haben diese Einladung zuvor angenommen'; -$labels['youhavepreviouslytentative'] = 'Sie haben diese Einladung zuvor mit Vorbehalt angenommen'; -$labels['youhavepreviouslydeclined'] = 'Sie haben diese Einladung zuvor abgelehnt'; -$labels['youhavepreviouslydelegated'] = 'Sie haben diese Einladung zuvor delegiert'; -$labels['youhavepreviouslyin-process'] = 'Sie haben diese Aufgabe zuvor als In Bearbeitung gemeldet'; -$labels['youhavepreviouslycompleted'] = 'Sie haben diese Einladung zuvor erledigt'; -$labels['youhavepreviouslyneeds-action'] = 'Ihre Antwort auf diese Einladung ist noch ausstehend'; -$labels['attendeeaccepted'] = 'Teilnehmer hat akzeptiert'; -$labels['attendeetentative'] = 'Teilnehmer hat mit Vorbehalt akzeptiert'; -$labels['attendeedeclined'] = 'Teilnehmer hat abgelehnt'; -$labels['attendeedelegated'] = 'Teilnehmer hat an $delegatedto delegiert'; -$labels['attendeein-process'] = 'Teilnehmer arbeitet an dieser Aufgabe'; -$labels['attendeecompleted'] = 'Teilnehmer hat die Aufgabe erledigt'; -$labels['notanattendee'] = 'Sie sind nicht in der Liste der Teilnehmer aufgeführt'; -$labels['outdatedinvitation'] = 'Diese Einladung wurde durch eine neuere Version ersetzt'; -$labels['importtocalendar'] = 'In Kalender übernehmen'; -$labels['removefromcalendar'] = 'Aus meinem Kalender löschen'; -$labels['updatemycopy'] = 'Meine Kopie aktualisieren'; -$labels['openpreview'] = 'Vorschau öffnen'; -$labels['deleteobjectconfirm'] = 'Möchten Sie dieses Objekt wirklich löschen?'; -$labels['declinedeleteconfirm'] = 'Soll das abgelehnte Objekt ebenfalls aus Ihrem Konto gelöscht werden?'; -$labels['delegateinvitation'] = 'Einladung delegieren'; -$labels['delegateto'] = 'Delegieren an'; -$labels['delegatersvpme'] = 'Informiere mich über Aktualisierungen dieses Termins'; -$labels['delegateinvalidaddress'] = 'Geben Sie eine gültige E-Mail-Adresse für den Delegierten ein'; -$labels['savingdata'] = 'Speichere...'; -$labels['savein'] = 'Speichern in'; -$labels['expandattendeegroup'] = 'Mit Gruppenmitgliedern ersetzen'; -$labels['expandattendeegroupnodata'] = 'Diese Gruppe konnte nicht ersetzt werden. Keine Gruppenmitglieder gefunden.'; -$labels['expandattendeegrouperror'] = 'Diese Gruppe konnte nicht ersetzt werden. Sie hat möglicherweise zuviele Mitglieder.'; -$labels['expandattendeegroupsizelimit'] = 'Die Gruppe hat zuviele Mitglieder und konnte deshalb nicht ersetzt werden.'; +$labels['rsvpmodeall'] = 'Die gesamte Terminserie'; +$labels['savingdata'] = 'Daten werden gespeichert...'; diff --git a/plugins/libkolab/localization/de.inc b/plugins/libkolab/localization/de.inc new file mode 100644 index 00000000..1a9af0e5 --- /dev/null +++ b/plugins/libkolab/localization/de.inc @@ -0,0 +1,25 @@ +CalDAV Client-Anwendung (z.B. Evolution oder Mozilla Thunderbird), um diese spezifische Aufgabenliste mit Ihrem Computer oder Mobilgerät zu synchronisieren.'; +$labels['newtask'] = 'Neue Aufgabe'; +$labels['createtask'] = 'Aufgabe erstellen '; +$labels['createnewtask'] = 'Neue Aufgabe erstellen (z.B. Samstag, Rasen mähen)'; +$labels['createfrommail'] = 'Aufgabe speichern'; +$labels['printtitle'] = 'Aufgaben drucken'; +$labels['printdescriptions'] = 'Beschreibungen drucken'; +$labels['mark'] = 'Markieren'; +$labels['unmark'] = 'Markierung entfernen'; +$labels['edit'] = 'Bearbeiten'; +$labels['delete'] = 'Löschen'; +$labels['title'] = 'Titel'; +$labels['description'] = 'Beschreibung'; +$labels['datetime'] = 'Fällig'; +$labels['duetime'] = 'Fällig'; +$labels['start'] = 'Beginn'; +$labels['starttime'] = 'Startzeit'; +$labels['alarms'] = 'Erinnerung'; +$labels['repeat'] = 'Wiederholung'; +$labels['links'] = 'Referenz'; +$labels['status'] = 'Status'; +$labels['status-needs-action'] = 'Braucht Aktion'; +$labels['status-in-process'] = 'In Bearbeitung'; +$labels['status-completed'] = 'Abgeschlossen'; +$labels['status-cancelled'] = 'Abgesagt'; +$labels['assignedto'] = 'Zugewiesen an'; +$labels['created'] = 'Erstellt'; +$labels['changed'] = 'Zuletzt geändert'; +$labels['taskoptions'] = 'Optionen'; +$labels['all'] = 'Alle'; +$labels['flagged'] = 'Markiert'; +$labels['complete'] = 'Abgeschlossen'; +$labels['completeness'] = 'Fortschritt'; +$labels['overdue'] = 'Überfällig'; +$labels['today'] = 'Heute'; +$labels['tomorrow'] = 'Morgen'; +$labels['next7days'] = 'Innerhalb von 7 Tagen'; +$labels['later'] = 'Später'; +$labels['assigned'] = 'Zugewiesen'; +$labels['assignedtitle'] = 'Aufgaben, welche an andere vergeben wurden'; +$labels['mytasks'] = 'Meine Aufgaben'; +$labels['mytaskstitle'] = 'An mich übertragene Aufgaben'; +$labels['nodate'] = 'Ohne Datum'; +$labels['removetag'] = 'Entfernen'; +$labels['removelink'] = 'E-Mail-Referenz entfernen'; +$labels['auto'] = 'Automatisch'; +$labels['newtask'] = 'Neue Aufgabe'; +$labels['edittask'] = 'Aufgabe ändern'; +$labels['save'] = 'Speichern'; +$labels['cancel'] = 'Abbrechen'; +$labels['saveandnotify'] = 'Speichern und Benachrichtigen'; +$labels['addsubtask'] = 'Teilaufgabe hinzufügen'; +$labels['deletetask'] = 'Aufgabe löschen'; +$labels['deletethisonly'] = 'Nur diese Aufgabe löschen'; +$labels['deletewithchilds'] = 'Mit allen Teilaufgaben löschen'; +$labels['taskactions'] = 'Aufgabeneinstellungen...'; +$labels['tabsummary'] = 'Titel'; +$labels['tabrecurrence'] = 'Wiederholung'; +$labels['tabassignments'] = 'Zuweisungen'; +$labels['tabattachments'] = 'Anhänge'; +$labels['tabsharing'] = 'Freigabe'; +$labels['editlist'] = 'Liste bearbeiten'; +$labels['createlist'] = 'Liste hinzufügen'; +$labels['listactions'] = 'Listeneinstellungen…'; +$labels['listname'] = 'Name'; +$labels['showalarms'] = 'Erinnerungen anzeigen'; +$labels['import'] = 'Importieren'; +$labels['viewactions'] = 'Ansicht-Aktionen'; +$labels['focusview'] = 'Nur diese Liste anzeigen'; +$labels['on'] = 'am'; +$labels['at'] = 'um'; +$labels['this'] = 'dies'; +$labels['next'] = 'weiter'; +$labels['yes'] = 'Ja'; +$labels['savingdata'] = 'Daten werden gespeichert…'; +$labels['errorsaving'] = 'Daten konnten nicht gespeichert werden.'; +$labels['notasksfound'] = 'Keine Aufgabe erfüllt die angelegten Kriterien'; +$labels['invalidstartduedates'] = 'Das Anfangsdatum muss vor dem Fälligkeitsdatum liegen.'; +$labels['invalidstartduetimes'] = 'Start- und Enddatum müssen entweder beide oder keins eine Zeit enthalten.'; +$labels['recurrencerequiresdate'] = 'Wiederkehrende Aufgaben erfordern entweder ein Start- oder Enddatum.'; +$labels['deletetasktconfirm'] = 'Diese Aufgabe wirklich löschen?'; +$labels['deleteparenttasktconfirm'] = 'Diese Aufgabe wirklich mit allen Teilaufgaben löschen?'; +$labels['deletelistconfirm'] = 'Diese Aufgabenliste wirklich mit allen Aufgaben löschen?'; +$labels['deletelistconfirmrecursive'] = 'Soll diese Liste wirklich mit allen Aufgaben und Unterlisten gelöscht werden?'; +$labels['aclnorights'] = 'Der Zugriff auf diese Aufgabenliste erfordert Administrator-Rechte.'; +$labels['changetaskconfirm'] = 'Aufgabe ändern'; +$labels['changeconfirmnotifications'] = 'Wollen Sie die beauftragten Teilnehmer über diese Änderung informieren?'; +$labels['partstatupdatenotification'] = 'Wollen Sie den Organisator über die Statusänderung benachrichtigen?'; +$labels['quickaddinput'] = 'Neue Aufgabe Datum und Titel'; +$labels['arialabelquickaddbox'] = 'Neue Aufgabe schnell hinzufügen'; +$labels['arialabelsearchform'] = 'Suchformular für Aufgaben'; +$labels['arialabelquicksearchbox'] = 'Sucheingabe für Aufgaben'; +$labels['arialabellistsearchform'] = 'Sucheingabe für Aufgabenlisten'; +$labels['arialabeltaskselector'] = 'Listenmodus'; +$labels['arialabeltasklisting'] = 'Aufgabenauflistung'; +$labels['arialabelsortmenu'] = 'Aufgaben-Sortierungsoptionen'; +$labels['attendee'] = 'Beauftragter'; +$labels['role'] = 'Rolle'; +$labels['availability'] = 'Verfüg.'; +$labels['confirmstate'] = 'Status'; +$labels['addattendee'] = 'Beauftragten hinzufügen'; +$labels['roleorganizer'] = 'Organisator'; +$labels['rolerequired'] = 'Erforderlich'; +$labels['roleoptional'] = 'Optional'; +$labels['rolechair'] = 'Vorsitz'; +$labels['rolenonparticipant'] = 'Beobachter'; +$labels['sendinvitations'] = 'Einladungen versenden'; +$labels['sendnotifications'] = 'Beauftragte Teilnehmer über die Änderung informieren'; +$labels['sendcancellation'] = 'Beauftragte Teilnehmer über die Stornierung informieren'; +$labels['invitationsubject'] = 'Ihnen wurde "$title" zugewiesen'; +$labels['invitationmailbody'] = "*\$title*\n\nFällig: \$date\n\nTeilnehmer: \$attendees\n\n\$description\n\nAngehängt finden Sie eine iCalendar-Datei mit allen Aufgabendetails, welche in Ihre Aufgabenanwendung importiert werden kann."; +$labels['itipupdatesubject'] = '"$title" wurde aktualisiert'; +$labels['itipupdatesubjectempty'] = 'Eine ihrer Aufgabe wurde aktualisiert'; +$labels['itipupdatemailbody'] = "*\$title*\n\nFällig: \$date\n\nTeilnehmer: \$attendees\n\nAngehängt finden Sie eine iCalendar-Datei mit den aktualisierten Aufgabendetails, welche in Ihre Aufgabenanwendung importiert werden kann."; +$labels['itipcancelsubject'] = '"$title" wurde abgesagt'; +$labels['itipcancelmailbody'] = "*\$title*\n\nFällig: \$date\n\nTeilnehmer: \$attendees\n\nDie Aufgabe wurde durch \$organizer storniert.\n\nAngehängt finden Sie eine iCalendar-Datei mit den aktualisierten Aufgabendetails."; +$labels['saveintasklist'] = 'speichern in'; +$labels['taskhistory'] = 'Historie'; +$labels['objectchangelog'] = 'Änderungshistorie'; +$labels['objectdiff'] = 'Änderungen aus $rev1 nach $rev2'; +$labels['objectnotfound'] = 'Fehler beim Laden der Aufgabendaten'; +$labels['objectchangelognotavailable'] = 'Änderung der Historie ist nicht verfügbar für diese Aufgabe.'; +$labels['objectdiffnotavailable'] = 'Vergleich für die gewählten Versionen nicht möglich'; +$labels['revisionrestoreconfirm'] = 'Möchten Sie wirklich die Version $rev dieser Aufgabe wiederherstellen? Dies wird die aktuelle Aufgabe mit der alten Version ersetzen.'; +$labels['objectrestoresuccess'] = 'Revision $rev erfolgreich wiederhergestellt'; +$labels['objectrestoreerror'] = 'Fehler beim Wiederherstellen der alten Revision'; +$labels['itipobjectnotfound'] = 'Die Aufgabe, auf welche sich diese Nachricht bezieht, wurde nicht in Ihrer Aufgabenliste gefunden.'; +$labels['itipmailbodyaccepted'] = "\$sender hat die Zuweisung folgender Aufgabe akzeptiert:\n\n*\$title*\n\nFällig: \$date\n\nVerantwortlich: \$attendees"; +$labels['itipmailbodytentative'] = "\$sender hat die Zuweisung folgender Aufgabe unter Vorbehalt akzeptiert:\n\n*\$title*\n\nFällig: \$date\n\nVerantwortlich: \$attendees"; +$labels['itipmailbodydeclined'] = "\$sender hat die Zuweisung folgender Aufgabe abgeleht:\n\n*\$title*\n\nFällig: \$date\n\nVerantwortlich: \$attendees"; +$labels['itipmailbodycancel'] = "\$sender hat die Zuweisung folgender Aufgabe abgeleht:\n\n*\$title*\n\nFällig: \$date"; +$labels['itipmailbodyin-process'] = "\$sender hat den Status folgender Aufgabe auf in-Bearbeitung gesetzt:\n\n*\$title*\n\nFällig: \$date"; +$labels['itipmailbodycompleted'] = "\$sender hat folgende Aufgabe abgeschlossen:\n\n*\$title*\n\nFällig: \$date"; +$labels['itipmailbodydelegated'] = "\$sender hat folgende Aufgabe delegiert:\n\n*\$title*\n\nFällig: \$date"; +$labels['itipmailbodydelegatedto'] = "\$sender hat folgende Aufgabe an Sie delegiert:\n\n*\$title*\n\nFällig: \$date"; +$labels['attendeeaccepted'] = 'Delegierter hat akzeptiert'; +$labels['attendeetentative'] = 'Delegierter hat unter Vorbehalt akzeptiert'; +$labels['attendeedeclined'] = 'Delegierter hat abgelehnt'; +$labels['attendeedelegated'] = 'Zugewiesener hat zu $delegatedto delegiert'; +$labels['attendeein-process'] = 'Delegierter ist in Bearbeitung '; +$labels['attendeecompleted'] = 'Delegierter hat abgeschlossen'; +$labels['acceptinvitation'] = 'Akzeptieren Sie die Zuweisung?'; +$labels['itipdeclinetask'] = 'Lehnen Sie to Zuweisung dieser Aufgabe ab'; +$labels['declinedeleteconfirm'] = 'Möchten Sie diese abgelehnete Aufgabe aus Ihrer Aufgabenliste löschen?'; +$labels['itipcomment'] = 'Kommentar zur Einladungs-/Benachrichtigungsnachricht'; +$labels['itipcommenttitle'] = 'Dieser Kommentar wird der Benachrichtigung an andere Delegierte hinzugefügt'; +$labels['itipsendsuccess'] = 'Benachrichtigung an Delegierte gesendet'; +$labels['errornotifying'] = 'Senden der Benachrichtigung an Delegierte fehlgeschlagen'; +$labels['removefromcalendar'] = 'Aus meinen Aufgaben entfernen'; +$labels['delegateinvitation'] = 'Zuweisung delegieren'; +$labels['andnmore'] = '$nr weitere...'; +$labels['savetotasklist'] = 'In den Aufgaben speichern'; +$labels['comment'] = 'Kommentar'; +$labels['rsvpcomment'] = 'Kommentar'; +$labels['errorimportingtask'] = 'Fehler beim Importieren der Aufgabe(n)'; +$labels['importwarningexists'] = 'Eine Kopie dieser Aufgabe exisistiert bereits in Ihrer Aufgabenliste'; +$labels['importsuccess'] = '$nr Aufgaben erfolgreich importiert'; +$labels['importerror'] = 'Fehler beim Importieren'; +$labels['newerversionexists'] = 'Eine neuere Version dieser Aufgabe existiert bereits! Abbruch.'; +$labels['nowritetasklistfound'] = 'Keine Aufgabenliste zum Speichern der Aufgabe gefunden'; +$labels['importedsuccessfully'] = 'Die Aufgabe wurde erfolgreich unter \'$list\' gespeichert'; +$labels['updatedsuccessfully'] = 'Die Aufgabe wurde erfolgreich in \'$list\' aktualisiert'; +$labels['attendeupdateesuccess'] = 'Teilnehmerstatus erfolgreich aktualisiert'; +$labels['itipresponseerror'] = 'Senden der Antwort auf diese Aufgabenzuweisung fehlgeschlagen'; +$labels['itipinvalidrequest'] = 'Diese Einladung ist nicht mehr gültig.'; +$labels['sentresponseto'] = 'Antwort auf Aufgabenzuweisung erfolgreich an $mailto versendet'; +$labels['successremoval'] = 'Diese Aufgabe wurde erfolgreich gelöscht.'; +$labels['invalidlistproperties'] = 'Ungültige Listeneigenschaften! Bitte einen gültigen Namen eingeben.'; diff --git a/plugins/tasklist/localization/de_DE.inc b/plugins/tasklist/localization/de_DE.inc index 9cbabad4..4ecccc01 100644 --- a/plugins/tasklist/localization/de_DE.inc +++ b/plugins/tasklist/localization/de_DE.inc @@ -9,184 +9,78 @@ $labels['navtitle'] = 'Aufgaben'; $labels['lists'] = 'Aufgabenlisten'; $labels['list'] = 'Aufgabenliste'; -$labels['tags'] = 'Schlagworte'; $labels['export'] = 'Exportieren'; -$labels['exporttitle'] = 'Kalender als iCalendar exportieren'; +$labels['exporttitle'] = 'Nach iCalendar exportieren'; $labels['exportattachments'] = 'Mit Anhängen'; -$labels['currentview'] = 'Aktuelle Ansicht'; -$labels['tasklistsubscribe'] = 'Permanent anzeigen'; -$labels['listsearchresults'] = 'Verfügbare Aufgaben'; -$labels['findlists'] = 'Finde Aufgabenlisten,..'; +$labels['currentview'] = 'aktuelle Ansicht'; +$labels['listsearchresults'] = 'Verfügbare Aufgabenlisten'; +$labels['findlists'] = 'Finde Aufgabenlisten...'; $labels['searchterms'] = 'Suchbegriffe'; $labels['notasklistsfound'] = 'Keine Aufgabenlisten gefunden'; $labels['nrtasklistsfound'] = '$nr Aufgabenlisten gefunden'; -$labels['removelist'] = 'Von der Liste entfernen'; -$labels['showcaldavurl'] = 'CalDAV URL anzeigen'; -$labels['caldavurldescription'] = 'Kopieren dieser Adresse in eine CalDAV Client-Anwendung (z.B. Evolution oder Mozilla Thunderbird), um diese spezifische Aufgabenliste mit Ihrem Computer oder Mobilgerät zu synchronisieren.'; +$labels['removelist'] = 'Aus Liste entfernen'; +$labels['showcaldavurl'] = 'Zeige CalDAV URL'; +$labels['caldavurldescription'] = 'Kopieren Sie diese Adresse in eine CalDAV-Client-Anwendung (z.B. Evolution oder Mozilla Thunderbird) um diese Aufgabenliste mit Ihrem Computer oder Mobilgerät zu synchronisieren.'; $labels['newtask'] = 'Neue Aufgabe'; $labels['createtask'] = 'Aufgabe erstellen '; $labels['createnewtask'] = 'Neue Aufgabe erstellen (z.B. Samstag, Rasen mähen)'; -$labels['createfrommail'] = 'Aufgabe speichern'; +$labels['createfrommail'] = 'Als Aufgabe speichern'; $labels['printtitle'] = 'Aufgaben drucken'; -$labels['printdescriptions'] = 'Beschreibungen drucken'; -$labels['mark'] = 'Markieren'; -$labels['unmark'] = 'Markierung entfernen'; $labels['edit'] = 'Bearbeiten'; $labels['delete'] = 'Löschen'; $labels['title'] = 'Titel'; $labels['description'] = 'Beschreibung'; -$labels['datetime'] = 'Fällig'; -$labels['duetime'] = 'Fällig'; -$labels['start'] = 'Beginn'; -$labels['starttime'] = 'Startzeit'; +$labels['start'] = 'Start'; +$labels['starttime'] = 'Beginn'; $labels['alarms'] = 'Erinnerung'; -$labels['repeat'] = 'Wiederholung'; -$labels['links'] = 'Referenz'; +$labels['repeat'] = 'Wiederholen'; $labels['status'] = 'Status'; -$labels['status-needs-action'] = 'Braucht Aktion'; -$labels['status-in-process'] = 'In Bearbeitung'; +$labels['status-needs-action'] = 'Bearbeitung erforderlich'; $labels['status-completed'] = 'Abgeschlossen'; -$labels['status-cancelled'] = 'Abgesagt'; +$labels['status-cancelled'] = 'Gekündigt'; $labels['assignedto'] = 'Zugewiesen an'; $labels['created'] = 'Erstellt'; -$labels['changed'] = 'Zuletzt geändert'; +$labels['changed'] = 'Zuletzt bearbeitet'; $labels['taskoptions'] = 'Optionen'; $labels['all'] = 'Alle'; -$labels['flagged'] = 'Markiert'; -$labels['complete'] = 'Abgeschlossen'; +$labels['complete'] = 'Erledigt'; $labels['completeness'] = 'Fortschritt'; $labels['overdue'] = 'Überfällig'; $labels['today'] = 'Heute'; $labels['tomorrow'] = 'Morgen'; -$labels['next7days'] = 'Innerhalb von 7 Tagen'; +$labels['next7days'] = 'Nächste 7 Tage'; $labels['later'] = 'Später'; -$labels['assigned'] = 'Zugewiesen'; -$labels['assignedtitle'] = 'Aufgaben, welche an andere vergeben wurden'; +$labels['assignedtitle'] = 'Aufgaben die Sie anderen Personen zugewiesen haben'; $labels['mytasks'] = 'Meine Aufgaben'; -$labels['mytaskstitle'] = 'An mich übertragene Aufgaben'; -$labels['nodate'] = 'Ohne Datum'; +$labels['mytaskstitle'] = 'Mir zugewiesene Aufgaben'; +$labels['nodate'] = 'kein Datum'; $labels['removetag'] = 'Entfernen'; -$labels['removelink'] = 'E-Mail-Referenz entfernen'; -$labels['auto'] = 'Automatisch'; $labels['newtask'] = 'Neue Aufgabe'; -$labels['edittask'] = 'Aufgabe ändern'; +$labels['edittask'] = 'Aufgabe bearbeiten'; $labels['save'] = 'Speichern'; $labels['cancel'] = 'Abbrechen'; -$labels['saveandnotify'] = 'Speichern und Benachrichtigen'; -$labels['addsubtask'] = 'Teilaufgabe hinzufügen'; -$labels['deletetask'] = 'Aufgabe löschen'; -$labels['deletethisonly'] = 'Nur diese Aufgabe löschen'; -$labels['deletewithchilds'] = 'Mit allen Teilaufgaben löschen'; -$labels['taskactions'] = 'Aufgabeneinstellungen...'; -$labels['tabsummary'] = 'Titel'; +$labels['addsubtask'] = 'Unteraufgabe hinzufügen'; +$labels['tabsummary'] = 'Zusammenfassung'; $labels['tabrecurrence'] = 'Wiederholung'; -$labels['tabassignments'] = 'Zuweisungen'; $labels['tabattachments'] = 'Anhänge'; -$labels['tabsharing'] = 'Freigabe'; -$labels['editlist'] = 'Liste bearbeiten'; -$labels['createlist'] = 'Liste hinzufügen'; -$labels['listactions'] = 'Listeneinstellungen…'; $labels['listname'] = 'Name'; -$labels['showalarms'] = 'Erinnerungen anzeigen'; -$labels['import'] = 'Importieren'; -$labels['viewactions'] = 'Ansicht-Aktionen'; -$labels['focusview'] = 'Nur diese Liste anzeigen'; -$labels['on'] = 'am'; -$labels['at'] = 'um'; -$labels['this'] = 'dies'; -$labels['next'] = 'weiter'; +$labels['at'] = 'am'; $labels['yes'] = 'Ja'; -$labels['savingdata'] = 'Daten werden gespeichert…'; -$labels['errorsaving'] = 'Daten konnten nicht gespeichert werden.'; -$labels['notasksfound'] = 'Keine Aufgabe erfüllt die angelegten Kriterien'; -$labels['invalidstartduedates'] = 'Das Anfangsdatum muss vor dem Fälligkeitsdatum liegen.'; -$labels['invalidstartduetimes'] = 'Start- und Enddatum müssen entweder beide oder keins eine Zeit enthalten.'; -$labels['recurrencerequiresdate'] = 'Wiederkehrende Aufgaben erfordern entweder ein Start- oder Enddatum.'; -$labels['deletetasktconfirm'] = 'Diese Aufgabe wirklich löschen?'; -$labels['deleteparenttasktconfirm'] = 'Diese Aufgabe wirklich mit allen Teilaufgaben löschen?'; -$labels['deletelistconfirm'] = 'Diese Aufgabenliste wirklich mit allen Aufgaben löschen?'; -$labels['deletelistconfirmrecursive'] = 'Soll diese Liste wirklich mit allen Aufgaben und Unterlisten gelöscht werden?'; -$labels['aclnorights'] = 'Der Zugriff auf diese Aufgabenliste erfordert Administrator-Rechte.'; -$labels['changetaskconfirm'] = 'Aufgabe ändern'; -$labels['changeconfirmnotifications'] = 'Wollen Sie die beauftragten Teilnehmer über diese Änderung informieren?'; -$labels['partstatupdatenotification'] = 'Wollen Sie den Organisator über die Statusänderung benachrichtigen?'; -$labels['quickaddinput'] = 'Neue Aufgabe Datum und Titel'; -$labels['arialabelquickaddbox'] = 'Neue Aufgabe schnell hinzufügen'; -$labels['arialabelsearchform'] = 'Suchformular für Aufgaben'; -$labels['arialabelquicksearchbox'] = 'Sucheingabe für Aufgaben'; -$labels['arialabellistsearchform'] = 'Sucheingabe für Aufgabenlisten'; -$labels['arialabeltaskselector'] = 'Listenmodus'; -$labels['arialabeltasklisting'] = 'Aufgabenauflistung'; -$labels['arialabelsortmenu'] = 'Aufgaben-Sortierungsoptionen'; -$labels['attendee'] = 'Beauftragter'; -$labels['role'] = 'Rolle'; -$labels['availability'] = 'Verfüg.'; +$labels['savingdata'] = 'Daten werden gespeichert...'; $labels['confirmstate'] = 'Status'; -$labels['addattendee'] = 'Beauftragten hinzufügen'; $labels['roleorganizer'] = 'Organisator'; -$labels['rolerequired'] = 'Erforderlich'; +$labels['rolerequired'] = 'Pflichtfeld'; $labels['roleoptional'] = 'Optional'; -$labels['rolechair'] = 'Vorsitz'; -$labels['rolenonparticipant'] = 'Beobachter'; -$labels['sendinvitations'] = 'Einladungen versenden'; -$labels['sendnotifications'] = 'Beauftragte Teilnehmer über die Änderung informieren'; -$labels['sendcancellation'] = 'Beauftragte Teilnehmer über die Stornierung informieren'; -$labels['invitationsubject'] = 'Ihnen wurde "$title" zugewiesen'; -$labels['invitationmailbody'] = "*\$title*\n\nFällig: \$date\n\nTeilnehmer: \$attendees\n\n\$description\n\nAngehängt finden Sie eine iCalendar-Datei mit allen Aufgabendetails, welche in Ihre Aufgabenanwendung importiert werden kann."; +$labels['rolechair'] = 'Vorsitzender'; $labels['itipupdatesubject'] = '"$title" wurde aktualisiert'; -$labels['itipupdatesubjectempty'] = 'Eine ihrer Aufgabe wurde aktualisiert'; -$labels['itipupdatemailbody'] = "*\$title*\n\nFällig: \$date\n\nTeilnehmer: \$attendees\n\nAngehängt finden Sie eine iCalendar-Datei mit den aktualisierten Aufgabendetails, welche in Ihre Aufgabenanwendung importiert werden kann."; $labels['itipcancelsubject'] = '"$title" wurde abgesagt'; -$labels['itipcancelmailbody'] = "*\$title*\n\nFällig: \$date\n\nTeilnehmer: \$attendees\n\nDie Aufgabe wurde durch \$organizer storniert.\n\nAngehängt finden Sie eine iCalendar-Datei mit den aktualisierten Aufgabendetails."; -$labels['saveintasklist'] = 'speichern in'; $labels['taskhistory'] = 'Historie'; $labels['objectchangelog'] = 'Änderungshistorie'; -$labels['objectdiff'] = 'Änderungen aus $rev1 nach $rev2'; -$labels['objectnotfound'] = 'Fehler beim Laden der Aufgabendaten'; -$labels['objectchangelognotavailable'] = 'Änderung der Historie ist nicht verfügbar für diese Aufgabe.'; -$labels['objectdiffnotavailable'] = 'Vergleich für die gewählten Versionen nicht möglich'; -$labels['revisionrestoreconfirm'] = 'Möchten Sie wirklich die Version $rev dieser Aufgabe wiederherstellen? Dies wird die aktuelle Aufgabe mit der alten Version ersetzen.'; -$labels['objectrestoresuccess'] = 'Revision $rev erfolgreich wiederhergestellt'; -$labels['objectrestoreerror'] = 'Fehler beim Wiederherstellen der alten Revision'; -$labels['itipobjectnotfound'] = 'Die Aufgabe, auf welche sich diese Nachricht bezieht, wurde nicht in Ihrer Aufgabenliste gefunden.'; -$labels['itipmailbodyaccepted'] = "\$sender hat die Zuweisung folgender Aufgabe akzeptiert:\n\n*\$title*\n\nFällig: \$date\n\nVerantwortlich: \$attendees"; -$labels['itipmailbodytentative'] = "\$sender hat die Zuweisung folgender Aufgabe unter Vorbehalt akzeptiert:\n\n*\$title*\n\nFällig: \$date\n\nVerantwortlich: \$attendees"; -$labels['itipmailbodydeclined'] = "\$sender hat die Zuweisung folgender Aufgabe abgeleht:\n\n*\$title*\n\nFällig: \$date\n\nVerantwortlich: \$attendees"; -$labels['itipmailbodycancel'] = "\$sender hat die Zuweisung folgender Aufgabe abgeleht:\n\n*\$title*\n\nFällig: \$date"; -$labels['itipmailbodyin-process'] = "\$sender hat den Status folgender Aufgabe auf in-Bearbeitung gesetzt:\n\n*\$title*\n\nFällig: \$date"; -$labels['itipmailbodycompleted'] = "\$sender hat folgende Aufgabe abgeschlossen:\n\n*\$title*\n\nFällig: \$date"; -$labels['itipmailbodydelegated'] = "\$sender hat folgende Aufgabe delegiert:\n\n*\$title*\n\nFällig: \$date"; -$labels['itipmailbodydelegatedto'] = "\$sender hat folgende Aufgabe an Sie delegiert:\n\n*\$title*\n\nFällig: \$date"; -$labels['attendeeaccepted'] = 'Delegierter hat akzeptiert'; -$labels['attendeetentative'] = 'Delegierter hat unter Vorbehalt akzeptiert'; -$labels['attendeedeclined'] = 'Delegierter hat abgelehnt'; -$labels['attendeedelegated'] = 'Zugewiesener hat zu $delegatedto delegiert'; -$labels['attendeein-process'] = 'Delegierter ist in Bearbeitung '; -$labels['attendeecompleted'] = 'Delegierter hat abgeschlossen'; -$labels['acceptinvitation'] = 'Akzeptieren Sie die Zuweisung?'; -$labels['itipdeclinetask'] = 'Lehnen Sie to Zuweisung dieser Aufgabe ab'; -$labels['declinedeleteconfirm'] = 'Möchten Sie diese abgelehnete Aufgabe aus Ihrer Aufgabenliste löschen?'; -$labels['itipcomment'] = 'Kommentar zur Einladungs-/Benachrichtigungsnachricht'; -$labels['itipcommenttitle'] = 'Dieser Kommentar wird der Benachrichtigung an andere Delegierte hinzugefügt'; -$labels['itipsendsuccess'] = 'Benachrichtigung an Delegierte gesendet'; -$labels['errornotifying'] = 'Senden der Benachrichtigung an Delegierte fehlgeschlagen'; -$labels['removefromcalendar'] = 'Aus meinen Aufgaben entfernen'; -$labels['delegateinvitation'] = 'Zuweisung delegieren'; -$labels['andnmore'] = '$nr weitere...'; -$labels['savetotasklist'] = 'In den Aufgaben speichern'; +$labels['objectdiff'] = 'Änderungen seit $rev1 bis $rev2'; +$labels['objectdiffnotavailable'] = 'Kein vergleich für die ausgewählten Stände möglich'; +$labels['objectrestoresuccess'] = 'Stand $rev erfolgreich wiederhergestellt'; +$labels['objectrestoreerror'] = 'Der alte Stand konnte nicht wiederhergestellt werden'; +$labels['andnmore'] = '$nr mehr...'; $labels['comment'] = 'Kommentar'; $labels['rsvpcomment'] = 'Kommentar'; -$labels['errorimportingtask'] = 'Fehler beim Importieren der Aufgabe(n)'; -$labels['importwarningexists'] = 'Eine Kopie dieser Aufgabe exisistiert bereits in Ihrer Aufgabenliste'; -$labels['importsuccess'] = '$nr Aufgaben erfolgreich importiert'; -$labels['importerror'] = 'Fehler beim Importieren'; -$labels['newerversionexists'] = 'Eine neuere Version dieser Aufgabe existiert bereits! Abbruch.'; -$labels['nowritetasklistfound'] = 'Keine Aufgabenliste zum Speichern der Aufgabe gefunden'; -$labels['importedsuccessfully'] = 'Die Aufgabe wurde erfolgreich unter \'$list\' gespeichert'; -$labels['updatedsuccessfully'] = 'Die Aufgabe wurde erfolgreich in \'$list\' aktualisiert'; -$labels['attendeupdateesuccess'] = 'Teilnehmerstatus erfolgreich aktualisiert'; -$labels['itipresponseerror'] = 'Senden der Antwort auf diese Aufgabenzuweisung fehlgeschlagen'; -$labels['itipinvalidrequest'] = 'Diese Einladung ist nicht mehr gültig.'; -$labels['sentresponseto'] = 'Antwort auf Aufgabenzuweisung erfolgreich an $mailto versendet'; -$labels['successremoval'] = 'Diese Aufgabe wurde erfolgreich gelöscht.'; -$labels['invalidlistproperties'] = 'Ungültige Listeneigenschaften! Bitte einen gültigen Namen eingeben.'; +$labels['itipinvalidrequest'] = 'Die Einladung ist nicht länger gültig'; From 56a469391419370b04133b4fce096fe9047a90c6 Mon Sep 17 00:00:00 2001 From: "Jeroen van Meeuwen (Kolab Systems)" Date: Wed, 19 Dec 2018 10:11:04 +0100 Subject: [PATCH 05/98] Update German translations by using de sources and de_DE sources for de_DE translations --- plugins/calendar/localization/de.inc | 269 ---------------- plugins/calendar/localization/de_DE.inc | 302 +++++++++++++----- plugins/kolab_2fa/localization/de.inc | 16 - plugins/kolab_2fa/localization/de_DE.inc | 8 +- plugins/kolab_activesync/localization/de.inc | 33 -- .../kolab_activesync/localization/de_DE.inc | 24 +- plugins/kolab_addressbook/localization/de.inc | 66 ---- .../kolab_addressbook/localization/de_DE.inc | 65 ++-- plugins/kolab_auth/localization/de.inc | 11 - plugins/kolab_auth/localization/de_DE.inc | 10 +- plugins/kolab_chat/localization/de.inc | 13 - plugins/kolab_delegation/localization/de.inc | 36 --- .../kolab_delegation/localization/de_DE.inc | 28 +- plugins/kolab_files/localization/de.inc | 152 --------- plugins/kolab_files/localization/de_DE.inc | 143 ++++++++- plugins/kolab_folders/localization/de.inc | 30 -- plugins/kolab_folders/localization/de_DE.inc | 18 +- plugins/kolab_notes/localization/de.inc | 62 ---- plugins/kolab_notes/localization/de_DE.inc | 49 +-- plugins/kolab_tags/localization/de.inc | 34 -- plugins/kolab_tags/localization/de_DE.inc | 29 +- plugins/libcalendaring/localization/de.inc | 162 ---------- plugins/libcalendaring/localization/de_DE.inc | 178 +++++++---- plugins/libkolab/localization/de.inc | 25 -- plugins/libkolab/localization/de_DE.inc | 24 +- plugins/tasklist/localization/de.inc | 192 ----------- plugins/tasklist/localization/de_DE.inc | 238 +++++++++++--- 27 files changed, 809 insertions(+), 1408 deletions(-) delete mode 100644 plugins/calendar/localization/de.inc delete mode 100644 plugins/kolab_2fa/localization/de.inc delete mode 100644 plugins/kolab_activesync/localization/de.inc delete mode 100644 plugins/kolab_addressbook/localization/de.inc delete mode 100644 plugins/kolab_auth/localization/de.inc delete mode 100644 plugins/kolab_chat/localization/de.inc delete mode 100644 plugins/kolab_delegation/localization/de.inc delete mode 100644 plugins/kolab_files/localization/de.inc delete mode 100644 plugins/kolab_folders/localization/de.inc delete mode 100644 plugins/kolab_notes/localization/de.inc delete mode 100644 plugins/kolab_tags/localization/de.inc delete mode 100644 plugins/libcalendaring/localization/de.inc delete mode 100644 plugins/libkolab/localization/de.inc delete mode 100644 plugins/tasklist/localization/de.inc diff --git a/plugins/calendar/localization/de.inc b/plugins/calendar/localization/de.inc deleted file mode 100644 index 1981504e..00000000 --- a/plugins/calendar/localization/de.inc +++ /dev/null @@ -1,269 +0,0 @@ -CalDAV-Klienten (z.B. Evolution oder Mozilla Thunderbird) kopieren, um den Kalender in Gänze mit einem mobilen Gerät zu synchronisieren.'; -$labels['findcalendars'] = 'Kalender finden …'; -$labels['searchterms'] = 'Suchbegriffe'; -$labels['calsearchresults'] = 'Verfügbare Kalender'; -$labels['calendarsubscribe'] = 'Permanent anzeigen'; -$labels['nocalendarsfound'] = 'Keine Kalender gefunden'; -$labels['nrcalendarsfound'] = '$nr Kalender gefunden'; -$labels['quickview'] = 'Nur diesen Kalender anzeigen'; -$labels['invitationspending'] = 'Ausstehende Einladungen'; -$labels['invitationsdeclined'] = 'Abgelehnte Einladungen'; -$labels['changepartstat'] = 'Teilnehmerstatus ändern'; -$labels['rsvpcomment'] = 'Einladungstext'; -$labels['listrange'] = 'Angezeigter Bereich:'; -$labels['listsections'] = 'Unterteilung:'; -$labels['smartsections'] = 'Intelligent'; -$labels['until'] = 'bis'; -$labels['today'] = 'Heute'; -$labels['tomorrow'] = 'Morgen'; -$labels['thisweek'] = 'Diese Woche'; -$labels['nextweek'] = 'Nächste Woche'; -$labels['prevweek'] = 'Vorige Woche'; -$labels['thismonth'] = 'Diesen Monat'; -$labels['nextmonth'] = 'Nächsten Monat'; -$labels['weekofyear'] = 'Woche'; -$labels['pastevents'] = 'Vergangene'; -$labels['futureevents'] = 'Zukünftige'; -$labels['showalarms'] = 'Erinnerungen anzeigen'; -$labels['defaultalarmtype'] = 'Standard-Erinnerungseinstellung'; -$labels['defaultalarmoffset'] = 'Standard-Erinnerungszeit'; -$labels['attendee'] = 'Teilnehmer'; -$labels['role'] = 'Rolle'; -$labels['availability'] = 'Verfüg.'; -$labels['confirmstate'] = 'Status'; -$labels['addattendee'] = 'Hinzufügen'; -$labels['roleorganizer'] = 'Organisator'; -$labels['rolerequired'] = 'Erforderlich'; -$labels['roleoptional'] = 'Optional'; -$labels['rolechair'] = 'Vorsitz'; -$labels['rolenonparticipant'] = 'Abwesend'; -$labels['cutypeindividual'] = 'Person'; -$labels['cutypegroup'] = 'Gruppe'; -$labels['cutyperesource'] = 'Ressource'; -$labels['cutyperoom'] = 'Raum'; -$labels['availfree'] = 'Frei'; -$labels['availbusy'] = 'Gebucht'; -$labels['availunknown'] = 'Unbekannt'; -$labels['availtentative'] = 'Mit Vorbehalt'; -$labels['availoutofoffice'] = 'Abwesend'; -$labels['scheduletime'] = 'Verfügbarkeit anzeigen'; -$labels['sendinvitations'] = 'Einladungen versenden'; -$labels['sendnotifications'] = 'Teilnehmer über die Änderungen informieren'; -$labels['sendcancellation'] = 'Teilnehmer über die Terminabsage informieren'; -$labels['onlyworkinghours'] = 'Verfügbarkeit innerhalb meiner Arbeitszeiten suchen'; -$labels['reqallattendees'] = 'Erforderliche/alle Teilnehmer'; -$labels['prevslot'] = 'Vorheriger Vorschlag'; -$labels['nextslot'] = 'Nächster Vorschlag'; -$labels['suggestedslot'] = 'Empfohlener Slot'; -$labels['noslotfound'] = 'Es konnten keine freien Zeiten gefunden werden'; -$labels['invitationsubject'] = 'Sie wurden zu »$title« eingeladen'; -$labels['invitationmailbody'] = "*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees\n\n\$description\n\nIm Anhang finden Sie eine iCalendar-Datei mit allen Details des Termins. Diese können Sie in Ihre Kalenderanwendung importieren."; -$labels['invitationattendlinks'] = "Falls Ihr E-Mail-Programm keine iTip-Anfragen unterstützt, können Sie den folgenden Link verwenden, um den Termin zu bestätigen oder abzulehnen:\n\$url"; -$labels['eventupdatesubject'] = '»$title« wurde aktualisiert'; -$labels['eventupdatesubjectempty'] = 'Termin wurde aktualisiert'; -$labels['eventupdatemailbody'] = "*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees\n\nIm Anhang finden Sie eine iCalendar-Datei mit den aktualisiereten Termindaten. Diese können Sie in Ihre Kalenderanwendung importieren."; -$labels['eventcancelsubject'] = '»$title« wurde abgesagt'; -$labels['eventcancelmailbody'] = "*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees\n\nDer Termin wurde von \$organizer abgesagt.\n\nIm Anhang finden Sie eine iCalendar-Datei mit den Termindaten."; -$labels['itipobjectnotfound'] = 'Der Termin auf den sich diese Nachricht bezieht, wurde in Ihrem Kalender nicht gefunden.'; -$labels['itipmailbodyaccepted'] = "\$sender hat die Einladung zum folgenden Termin angenommen:\n\n*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees"; -$labels['itipmailbodytentative'] = "\$sender hat die Einladung mit Vorbehalt zum folgenden Termin angenommen:\n\n*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees"; -$labels['itipmailbodydeclined'] = "\$sender hat die Einladung zum folgenden Termin abgelehnt:\n\n*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees"; -$labels['itipmailbodycancel'] = "\$sender hat Ihre Teilnahme bei der folgenden Veranstaltung zurückgewiesen:\n\n*\$title*\n\nWann: \$date"; -$labels['itipmailbodydelegated'] = "\$sender hat die Teilnahme an folgendem Event delegiert:\n\n*\$title*\n\nWhen: \$date"; -$labels['itipmailbodydelegatedto'] = "\$sender hat die Teilnahme an folgendem Event an Sie delegiert:\n\n*\$title*\n\nWann: \$date"; -$labels['itipdeclineevent'] = 'Möchten Sie die Einladung zu diesem Termin ablehnen?'; -$labels['declinedeleteconfirm'] = 'Soll der abgelehnte Termin zusätzlich aus dem Kalender gelöscht werden?'; -$labels['itipcomment'] = 'Kommentar zur Einladungs-/Benachrichtigungsnachricht'; -$labels['itipcommenttitle'] = 'Dieser Kommentar wird an die Einladungs-/Benachrichtigungsnachricht angehängt, die an die Teilnehmer verschickt wird'; -$labels['notanattendee'] = 'Sie sind nicht in der Liste der Teilnehmer aufgeführt'; -$labels['eventcancelled'] = 'Der Termin wurde vom Organisator abgesagt'; -$labels['saveincalendar'] = 'speichern in'; -$labels['updatemycopy'] = 'In meinem Kalender aktualisieren'; -$labels['savetocalendar'] = 'In Kalender übernehmen'; -$labels['openpreview'] = 'Kalender überprüfen'; -$labels['noearlierevents'] = 'Keine früheren Ereignisse'; -$labels['nolaterevents'] = 'Keine späteren Ereignisse'; -$labels['resource'] = 'Ressource'; -$labels['addresource'] = 'Ressource buchen'; -$labels['findresources'] = 'Ressourcen finden'; -$labels['resourcedetails'] = 'Details'; -$labels['resourceavailability'] = 'Verfügbarkeit'; -$labels['resourceowner'] = 'Eigentümer'; -$labels['resourceadded'] = 'Diese Ressource wurde Ihrem Termin hinzugefügt'; -$labels['tabsummary'] = 'Übersicht'; -$labels['tabrecurrence'] = 'Wiederholung'; -$labels['tabattendees'] = 'Teilnehmer'; -$labels['tabresources'] = 'Ressourcen'; -$labels['tabattachments'] = 'Anhänge'; -$labels['tabsharing'] = 'Freigabe'; -$labels['deleteobjectconfirm'] = 'Möchten Sie diesen Termin wirklich löschen?'; -$labels['deleteventconfirm'] = 'Möchten Sie diesen Termin wirklich löschen?'; -$labels['deletecalendarconfirm'] = 'Möchten Sie diesen Kalender mit allen Terminen wirklich löschen?'; -$labels['deletecalendarconfirmrecursive'] = 'Soll dieser Kalender wirklich mit allen Terminen und Unterkalendern gelöscht werden?'; -$labels['savingdata'] = 'Daten werden gespeichert …'; -$labels['errorsaving'] = 'Fehler beim Speichern.'; -$labels['operationfailed'] = 'Die Aktion ist fehlgeschlagen.'; -$labels['invalideventdates'] = 'Ungültige Daten eingegeben! Bitte überprüfen Sie die Eingaben.'; -$labels['invalidcalendarproperties'] = 'Ungültige Kalenderinformationen! Bitte geben Sie einen Namen ein.'; -$labels['searchnoresults'] = 'Keine Termine in den gewählten Kalendern gefunden.'; -$labels['successremoval'] = 'Der Termin wurde erfolgreich gelöscht.'; -$labels['successrestore'] = 'Der Termin wurde erfolgreich wieder hergestellt.'; -$labels['errornotifying'] = 'Benachrichtigung an die Teilnehmer konnten nicht gesendet werden'; -$labels['errorimportingevent'] = 'Fehler beim Importieren'; -$labels['importwarningexists'] = 'Eine Kopie dieses Termins existiert bereits in Ihrem Kalender.'; -$labels['newerversionexists'] = 'Eine neuere Version dieses Termins exisitert bereits! Import abgebrochen.'; -$labels['nowritecalendarfound'] = 'Kein Kalender zum Speichern gefunden'; -$labels['importedsuccessfully'] = 'Der Termin wurde erfolgreich in »$calendar« gespeichert'; -$labels['updatedsuccessfully'] = 'Der Termin wurde erfolgreich in »$calendar« geändert'; -$labels['attendeupdateesuccess'] = 'Teilnehmerstatus erfolgreich aktualisiert'; -$labels['itipsendsuccess'] = 'Einladung an Teilnehmer versendet.'; -$labels['itipresponseerror'] = 'Die Antwort auf diese Einladung konnte nicht versendet werden'; -$labels['itipinvalidrequest'] = 'Diese Einladung ist nicht mehr gültig.'; -$labels['sentresponseto'] = 'Antwort auf diese Einladung erfolgreich an $mailto gesendet'; -$labels['localchangeswarning'] = 'Die auszuführenden Änderungen werden sich nur auf den persönlichen Kalender auswirken und nicht an den Organisator des Termins weitergeleitet.'; -$labels['importsuccess'] = 'Es wurden $nr Termine erfolgreich importiert'; -$labels['importnone'] = 'Keine Termine zum Importieren gefunden'; -$labels['importerror'] = 'Fehler beim Importieren'; -$labels['aclnorights'] = 'Der Zugriff auf diesen Kalender erfordert Administrator-Rechte.'; -$labels['changeeventconfirm'] = 'Termin ändern'; -$labels['removeeventconfirm'] = 'Termin löschen'; -$labels['changerecurringeventwarning'] = 'Dies ist eine Terminreihe. Möchten Sie nur den aktuellen, diesen und alle zukünftigen oder alle Termine bearbeiten oder die Änderungen als neuen Termin speichern?'; -$labels['removerecurringeventwarning'] = 'Dies ist ein wiederkehrender Termin. Wollen Sie nur diesen Termin bearbeiten oder alle zukünftigen Vorkommen? Alternativ können auch alle Vorkommen bearbeitet werden.'; -$labels['removerecurringallonly'] = 'Dieses ist ein wiederkehrender Termin. Als ein Teilnehmer können Sie nur den gesamten Termin inklusive aller Wiederholungen löschen.'; -$labels['currentevent'] = 'Aktuellen'; -$labels['futurevents'] = 'Zukünftige'; -$labels['allevents'] = 'Alle'; -$labels['saveasnew'] = 'Als neu speichern'; -$labels['birthdays'] = 'Geburtstage'; -$labels['birthdayscalendar'] = 'Geburtstagskalender'; -$labels['displaybirthdayscalendar'] = 'Geburtstagskalender anzeigen'; -$labels['birthdayscalendarsources'] = 'Für diese Adressbücher'; -$labels['birthdayeventtitle'] = '$names Geburtstag'; -$labels['birthdayage'] = 'Alter $age'; -$labels['objectchangelog'] = 'Änderungsverlauf'; -$labels['objectdiff'] = 'Änderungen aus $rev1 nach $rev2'; -$labels['objectnotfound'] = 'Termindaten sind leider nicht vergübar'; -$labels['objectchangelognotavailable'] = 'Änderungshistorie ist nicht verfügbar für diesen Termin'; -$labels['objectdiffnotavailable'] = 'Vergleich für die gewählten Versionen nicht möglich'; -$labels['revisionrestoreconfirm'] = 'Wollen Sie wirklich die Version $rev dieses Termins wiederherstellen? Diese Aktion wird die aktuelle Kopie mit der älteren Version ersetzen.'; -$labels['objectrestoresuccess'] = 'Revision $rev erfolgreich wiederhergestellt'; -$labels['objectrestoreerror'] = 'Fehler beim Wiederherstellen der alten Revision'; -$labels['arialabelminical'] = 'Kalender Datumswahl'; -$labels['arialabelcalendarview'] = 'Kalender Ansicht'; -$labels['arialabelsearchform'] = 'Suchformular für Termine'; -$labels['arialabelquicksearchbox'] = 'Sucheingabe für Termine'; -$labels['arialabelcalsearchform'] = 'Suchformular für Kalender'; -$labels['calendaractions'] = 'Kalenderaktionen'; -$labels['arialabeleventattendees'] = 'Teilehmerliste'; -$labels['arialabeleventresources'] = 'Liste der Terminressourcen'; -$labels['arialabelresourcesearchform'] = 'Suchformular für Ressourcen'; -$labels['arialabelresourceselection'] = 'Verfügbare Ressourcen'; -?> diff --git a/plugins/calendar/localization/de_DE.inc b/plugins/calendar/localization/de_DE.inc index 6682f28f..ce421c59 100644 --- a/plugins/calendar/localization/de_DE.inc +++ b/plugins/calendar/localization/de_DE.inc @@ -1,25 +1,26 @@ CalDAV-Client-Anwendung (z.B. Evolution oder Mozilla Thunderbird) um diesen Kalender mit Ihrem Computer oder Mobilgerät zu synchronisieren.'; -$labels['findcalendars'] = 'Finde Kalender...'; +$labels['showurl'] = 'URL anzeigen'; +$labels['showurldescription'] = 'Über die folgende Adresse können Sie mit einem beliebigen Kalenderprogramm Ihren Kalender abrufen (nur lesend), sofern dieses das iCal-Format unterstützt.'; +$labels['caldavurldescription'] = 'Diese Adresse in einen CalDAV-Klienten (z.B. Evolution oder Mozilla Thunderbird) kopieren, um den Kalender in Gänze mit einem mobilen Gerät zu synchronisieren.'; +$labels['findcalendars'] = 'Kalender finden …'; $labels['searchterms'] = 'Suchbegriffe'; $labels['calsearchresults'] = 'Verfügbare Kalender'; +$labels['calendarsubscribe'] = 'Permanent anzeigen'; $labels['nocalendarsfound'] = 'Keine Kalender gefunden'; $labels['nrcalendarsfound'] = '$nr Kalender gefunden'; +$labels['quickview'] = 'Nur diesen Kalender anzeigen'; $labels['invitationspending'] = 'Ausstehende Einladungen'; $labels['invitationsdeclined'] = 'Abgelehnte Einladungen'; -$labels['changepartstat'] = 'Status des Teilnehmers ändern'; +$labels['changepartstat'] = 'Teilnehmerstatus ändern'; $labels['rsvpcomment'] = 'Einladungstext'; +$labels['listrange'] = 'Angezeigter Bereich:'; +$labels['listsections'] = 'Unterteilung:'; +$labels['smartsections'] = 'Intelligent'; $labels['until'] = 'bis'; $labels['today'] = 'Heute'; $labels['tomorrow'] = 'Morgen'; $labels['thisweek'] = 'Diese Woche'; $labels['nextweek'] = 'Nächste Woche'; $labels['prevweek'] = 'Vorige Woche'; -$labels['thismonth'] = 'Dieser Monat'; -$labels['nextmonth'] = 'Nächster Monat'; +$labels['thismonth'] = 'Diesen Monat'; +$labels['nextmonth'] = 'Nächsten Monat'; $labels['weekofyear'] = 'Woche'; -$labels['pastevents'] = 'Vergangenheit'; -$labels['futureevents'] = 'Zukunft'; +$labels['pastevents'] = 'Vergangene'; +$labels['futureevents'] = 'Zukünftige'; +$labels['showalarms'] = 'Erinnerungen anzeigen'; +$labels['defaultalarmtype'] = 'Standard-Erinnerungseinstellung'; +$labels['defaultalarmoffset'] = 'Standard-Erinnerungszeit'; $labels['attendee'] = 'Teilnehmer'; +$labels['role'] = 'Rolle'; +$labels['availability'] = 'Verfüg.'; $labels['confirmstate'] = 'Status'; -$labels['addattendee'] = 'Teilnehmer hinzufügen'; -$labels['roleorganizer'] = 'Veranstalter'; -$labels['rolerequired'] = 'Pflichtfeld'; +$labels['addattendee'] = 'Hinzufügen'; +$labels['roleorganizer'] = 'Organisator'; +$labels['rolerequired'] = 'Erforderlich'; $labels['roleoptional'] = 'Optional'; -$labels['rolechair'] = 'Vorsitzender'; +$labels['rolechair'] = 'Vorsitz'; $labels['rolenonparticipant'] = 'Abwesend'; +$labels['cutypeindividual'] = 'Person'; $labels['cutypegroup'] = 'Gruppe'; -$labels['cutyperesource'] = 'Hilfsmittel'; +$labels['cutyperesource'] = 'Ressource'; $labels['cutyperoom'] = 'Raum'; $labels['availfree'] = 'Frei'; -$labels['availbusy'] = 'Beschäftigt'; +$labels['availbusy'] = 'Gebucht'; $labels['availunknown'] = 'Unbekannt'; $labels['availtentative'] = 'Mit Vorbehalt'; -$labels['prevslot'] = 'Vorheriges Zeitfenster'; -$labels['nextslot'] = 'Nächstes Zeitfenster'; -$labels['suggestedslot'] = 'Vorgeschlagenes Zeitfenster'; -$labels['noslotfound'] = 'Es konnte kein freies Zeitfenster gefunden werden'; -$labels['invitationattendlinks'] = "Falls Ihr Email-Client iTip-Anfragen nicht unterstützt können Sie den folgenden Link benutzen um die Einlaudng entweder abzulehnen oder anzunehmen:\n\$url"; -$labels['eventupdatesubject'] = '"$title" wurde aktualisiert'; -$labels['eventupdatesubjectempty'] = 'Ein Termin der sie betrifft wurde aktualisiert'; -$labels['eventcancelsubject'] = '"$title" wurde abgesagt'; -$labels['itipdeclineevent'] = 'Wollen Sie Ihre Einladung zu diesem Termin ablehnen?'; -$labels['declinedeleteconfirm'] = 'Möchten Sie den abgelehnten Termin außerdem aus Ihrem Kalender löschen?'; -$labels['eventcancelled'] = 'Der Termin wurde abgesagt'; -$labels['openpreview'] = 'Kalender prüfen'; -$labels['noearlierevents'] = 'Keine früheren Termine'; -$labels['nolaterevents'] = 'Keine späteren Termine'; -$labels['resource'] = 'Hilfsmittel'; -$labels['addresource'] = 'Hilfsmittel buchen'; -$labels['findresources'] = 'Hilfsmittel finden'; +$labels['availoutofoffice'] = 'Abwesend'; +$labels['scheduletime'] = 'Verfügbarkeit anzeigen'; +$labels['sendinvitations'] = 'Einladungen versenden'; +$labels['sendnotifications'] = 'Teilnehmer über die Änderungen informieren'; +$labels['sendcancellation'] = 'Teilnehmer über die Terminabsage informieren'; +$labels['onlyworkinghours'] = 'Verfügbarkeit innerhalb meiner Arbeitszeiten suchen'; +$labels['reqallattendees'] = 'Erforderliche/alle Teilnehmer'; +$labels['prevslot'] = 'Vorheriger Vorschlag'; +$labels['nextslot'] = 'Nächster Vorschlag'; +$labels['suggestedslot'] = 'Empfohlener Slot'; +$labels['noslotfound'] = 'Es konnten keine freien Zeiten gefunden werden'; +$labels['invitationsubject'] = 'Sie wurden zu »$title« eingeladen'; +$labels['invitationmailbody'] = '*$title* + +Wann: $date + +Teilnehmer: $attendees + +$description + +Im Anhang finden Sie eine iCalendar-Datei mit allen Details des Termins. Diese können Sie in Ihre Kalenderanwendung importieren.'; +$labels['invitationattendlinks'] = 'Falls Ihr E-Mail-Programm keine iTip-Anfragen unterstützt, können Sie den folgenden Link verwenden, um den Termin zu bestätigen oder abzulehnen: +$url'; +$labels['eventupdatesubject'] = '»$title« wurde aktualisiert'; +$labels['eventupdatesubjectempty'] = 'Termin wurde aktualisiert'; +$labels['eventupdatemailbody'] = '*$title* + +Wann: $date + +Teilnehmer: $attendees + +Im Anhang finden Sie eine iCalendar-Datei mit den aktualisiereten Termindaten. Diese können Sie in Ihre Kalenderanwendung importieren.'; +$labels['eventcancelsubject'] = '»$title« wurde abgesagt'; +$labels['eventcancelmailbody'] = '*$title* + +Wann: $date + +Teilnehmer: $attendees + +Der Termin wurde von $organizer abgesagt. + +Im Anhang finden Sie eine iCalendar-Datei mit den Termindaten.'; +$labels['itipobjectnotfound'] = 'Der Termin auf den sich diese Nachricht bezieht, wurde in Ihrem Kalender nicht gefunden.'; +$labels['itipmailbodyaccepted'] = '$sender hat die Einladung zum folgenden Termin angenommen: + +*$title* + +Wann: $date + +Teilnehmer: $attendees'; +$labels['itipmailbodytentative'] = '$sender hat die Einladung mit Vorbehalt zum folgenden Termin angenommen: + +*$title* + +Wann: $date + +Teilnehmer: $attendees'; +$labels['itipmailbodydeclined'] = '$sender hat die Einladung zum folgenden Termin abgelehnt: + +*$title* + +Wann: $date + +Teilnehmer: $attendees'; +$labels['itipmailbodycancel'] = '$sender hat Ihre Teilnahme bei der folgenden Veranstaltung zurückgewiesen: + +*$title* + +Wann: $date'; +$labels['itipmailbodydelegated'] = '$sender hat die Teilnahme an folgendem Event delegiert: + +*$title* + +When: $date'; +$labels['itipmailbodydelegatedto'] = '$sender hat die Teilnahme an folgendem Event an Sie delegiert: + +*$title* + +Wann: $date'; +$labels['itipdeclineevent'] = 'Möchten Sie die Einladung zu diesem Termin ablehnen?'; +$labels['declinedeleteconfirm'] = 'Soll der abgelehnte Termin zusätzlich aus dem Kalender gelöscht werden?'; +$labels['itipcomment'] = 'Kommentar zur Einladungs-/Benachrichtigungsnachricht'; +$labels['itipcommenttitle'] = 'Dieser Kommentar wird an die Einladungs-/Benachrichtigungsnachricht angehängt, die an die Teilnehmer verschickt wird'; +$labels['notanattendee'] = 'Sie sind nicht in der Liste der Teilnehmer aufgeführt'; +$labels['eventcancelled'] = 'Der Termin wurde vom Organisator abgesagt'; +$labels['saveincalendar'] = 'speichern in'; +$labels['updatemycopy'] = 'In meinem Kalender aktualisieren'; +$labels['savetocalendar'] = 'In Kalender übernehmen'; +$labels['openpreview'] = 'Kalender überprüfen'; +$labels['noearlierevents'] = 'Keine früheren Ereignisse'; +$labels['nolaterevents'] = 'Keine späteren Ereignisse'; +$labels['resource'] = 'Ressource'; +$labels['addresource'] = 'Ressource buchen'; +$labels['findresources'] = 'Ressourcen finden'; $labels['resourcedetails'] = 'Details'; $labels['resourceavailability'] = 'Verfügbarkeit'; $labels['resourceowner'] = 'Eigentümer'; -$labels['resourceadded'] = 'Das Hilfsmittel wurde ihrem Termin hinzugefügt'; -$labels['tabsummary'] = 'Zusammenfassung'; +$labels['resourceadded'] = 'Diese Ressource wurde Ihrem Termin hinzugefügt'; +$labels['tabsummary'] = 'Übersicht'; $labels['tabrecurrence'] = 'Wiederholung'; $labels['tabattendees'] = 'Teilnehmer'; $labels['tabresources'] = 'Ressourcen'; $labels['tabattachments'] = 'Anhänge'; +$labels['tabsharing'] = 'Freigabe'; $labels['deleteobjectconfirm'] = 'Möchten Sie diesen Termin wirklich löschen?'; $labels['deleteventconfirm'] = 'Möchten Sie diesen Termin wirklich löschen?'; -$labels['deletecalendarconfirm'] = 'Möchten Sie diesen Kalender mit allen darin enthaltenen Terminen wirklich löschen?'; -$labels['deletecalendarconfirmrecursive'] = 'Möchten Sie diesen Kalender mit allen darin enthaltenen Terminen und enthaltenen Unterkalendern wirklich löschen?'; -$labels['savingdata'] = 'Daten werden gespeichert...'; -$labels['searchnoresults'] = 'Keine Termine in den ausgewählten Kalendern gefunden.'; +$labels['deletecalendarconfirm'] = 'Möchten Sie diesen Kalender mit allen Terminen wirklich löschen?'; +$labels['deletecalendarconfirmrecursive'] = 'Soll dieser Kalender wirklich mit allen Terminen und Unterkalendern gelöscht werden?'; +$labels['savingdata'] = 'Daten werden gespeichert …'; +$labels['errorsaving'] = 'Fehler beim Speichern.'; +$labels['operationfailed'] = 'Die Aktion ist fehlgeschlagen.'; +$labels['invalideventdates'] = 'Ungültige Daten eingegeben! Bitte überprüfen Sie die Eingaben.'; +$labels['invalidcalendarproperties'] = 'Ungültige Kalenderinformationen! Bitte geben Sie einen Namen ein.'; +$labels['searchnoresults'] = 'Keine Termine in den gewählten Kalendern gefunden.'; $labels['successremoval'] = 'Der Termin wurde erfolgreich gelöscht.'; -$labels['successrestore'] = 'Der Termin wurde erfolgreich wiederhergestellt.'; -$labels['itipsendsuccess'] = 'Einladung an die Teilnehmer versendet.'; -$labels['itipinvalidrequest'] = 'Die Einladung ist nicht länger gültig'; +$labels['successrestore'] = 'Der Termin wurde erfolgreich wieder hergestellt.'; +$labels['errornotifying'] = 'Benachrichtigung an die Teilnehmer konnten nicht gesendet werden'; +$labels['errorimportingevent'] = 'Fehler beim Importieren'; +$labels['importwarningexists'] = 'Eine Kopie dieses Termins existiert bereits in Ihrem Kalender.'; +$labels['newerversionexists'] = 'Eine neuere Version dieses Termins exisitert bereits! Import abgebrochen.'; +$labels['nowritecalendarfound'] = 'Kein Kalender zum Speichern gefunden'; +$labels['importedsuccessfully'] = 'Der Termin wurde erfolgreich in »$calendar« gespeichert'; +$labels['updatedsuccessfully'] = 'Der Termin wurde erfolgreich in »$calendar« geändert'; +$labels['attendeupdateesuccess'] = 'Teilnehmerstatus erfolgreich aktualisiert'; +$labels['itipsendsuccess'] = 'Einladung an Teilnehmer versendet.'; +$labels['itipresponseerror'] = 'Die Antwort auf diese Einladung konnte nicht versendet werden'; +$labels['itipinvalidrequest'] = 'Diese Einladung ist nicht mehr gültig.'; +$labels['sentresponseto'] = 'Antwort auf diese Einladung erfolgreich an $mailto gesendet'; +$labels['localchangeswarning'] = 'Die auszuführenden Änderungen werden sich nur auf den persönlichen Kalender auswirken und nicht an den Organisator des Termins weitergeleitet.'; +$labels['importsuccess'] = 'Es wurden $nr Termine erfolgreich importiert'; +$labels['importnone'] = 'Keine Termine zum Importieren gefunden'; +$labels['importerror'] = 'Fehler beim Importieren'; +$labels['aclnorights'] = 'Der Zugriff auf diesen Kalender erfordert Administrator-Rechte.'; $labels['changeeventconfirm'] = 'Termin ändern'; $labels['removeeventconfirm'] = 'Termin löschen'; -$labels['futurevents'] = 'Zukunft'; +$labels['changerecurringeventwarning'] = 'Dies ist eine Terminreihe. Möchten Sie nur den aktuellen, diesen und alle zukünftigen oder alle Termine bearbeiten oder die Änderungen als neuen Termin speichern?'; +$labels['removerecurringeventwarning'] = 'Dies ist ein wiederkehrender Termin. Wollen Sie nur diesen Termin bearbeiten oder alle zukünftigen Vorkommen? Alternativ können auch alle Vorkommen bearbeitet werden.'; +$labels['removerecurringallonly'] = 'Dieses ist ein wiederkehrender Termin. Als ein Teilnehmer können Sie nur den gesamten Termin inklusive aller Wiederholungen löschen.'; +$labels['currentevent'] = 'Aktuellen'; +$labels['futurevents'] = 'Zukünftige'; $labels['allevents'] = 'Alle'; +$labels['saveasnew'] = 'Als neu speichern'; $labels['birthdays'] = 'Geburtstage'; $labels['birthdayscalendar'] = 'Geburtstagskalender'; -$labels['displaybirthdayscalendar'] = 'Zeige Geburtstagskalender'; -$labels['birthdayeventtitle'] = 'Geburtstag von $name'; +$labels['displaybirthdayscalendar'] = 'Geburtstagskalender anzeigen'; +$labels['birthdayscalendarsources'] = 'Für diese Adressbücher'; +$labels['birthdayeventtitle'] = '$names Geburtstag'; $labels['birthdayage'] = 'Alter $age'; -$labels['objectchangelog'] = 'Änderungshistorie'; -$labels['objectdiff'] = 'Änderungen seit $rev1 bis $rev2'; -$labels['objectdiffnotavailable'] = 'Kein vergleich für die ausgewählten Stände möglich'; -$labels['objectrestoresuccess'] = 'Stand $rev erfolgreich wiederhergestellt'; -$labels['objectrestoreerror'] = 'Der alte Stand konnte nicht wiederhergestellt werden'; -$labels['arialabelcalendarview'] = 'Kalenderansicht'; -$labels['arialabeleventresources'] = 'Liste der Hilfsmittel des Termins'; -$labels['arialabelresourceselection'] = 'Verfügbare Hilfsmittel'; -?> +$labels['objectchangelog'] = 'Änderungsverlauf'; +$labels['objectdiff'] = 'Änderungen aus $rev1 nach $rev2'; +$labels['objectnotfound'] = 'Termindaten sind leider nicht vergübar'; +$labels['objectchangelognotavailable'] = 'Änderungshistorie ist nicht verfügbar für diesen Termin'; +$labels['objectdiffnotavailable'] = 'Vergleich für die gewählten Versionen nicht möglich'; +$labels['revisionrestoreconfirm'] = 'Wollen Sie wirklich die Version $rev dieses Termins wiederherstellen? Diese Aktion wird die aktuelle Kopie mit der älteren Version ersetzen.'; +$labels['objectrestoresuccess'] = 'Revision $rev erfolgreich wiederhergestellt'; +$labels['objectrestoreerror'] = 'Fehler beim Wiederherstellen der alten Revision'; +$labels['arialabelminical'] = 'Kalender Datumswahl'; +$labels['arialabelcalendarview'] = 'Kalender Ansicht'; +$labels['arialabelsearchform'] = 'Suchformular für Termine'; +$labels['arialabelquicksearchbox'] = 'Sucheingabe für Termine'; +$labels['arialabelcalsearchform'] = 'Suchformular für Kalender'; +$labels['calendaractions'] = 'Kalenderaktionen'; +$labels['arialabeleventattendees'] = 'Teilehmerliste'; +$labels['arialabeleventresources'] = 'Liste der Terminressourcen'; +$labels['arialabelresourcesearchform'] = 'Suchformular für Ressourcen'; +$labels['arialabelresourceselection'] = 'Verfügbare Ressourcen'; diff --git a/plugins/kolab_2fa/localization/de.inc b/plugins/kolab_2fa/localization/de.inc deleted file mode 100644 index 814c0777..00000000 --- a/plugins/kolab_2fa/localization/de.inc +++ /dev/null @@ -1,16 +0,0 @@ -
Um ein Gerät zu registrieren, bitte zuerst nach der Anleitung von dieser Seite mit dem Server verbinden. Anschließend sollte das Gerät für die Konfiguration hier zur Verfügung stehen.'; -$labels['savingdata'] = 'Daten werden gespeichert...'; -$labels['savingerror'] = 'Fehler beim Speichern der Konfiguration'; -$labels['notsupported'] = 'Ihr Server unterstützt keine Activesync-Konfiguration'; -$labels['devicedeleteconfirm'] = 'Wollen Sie wirklich alle Einstellungen für dieses Gerät löschen?'; -$labels['successfullydeleted'] = 'Die Geräteinstellungen wurden erfolgreich gelöscht'; -$labels['devicenotfound'] = 'Es kann nicht auf die Gerätekonfiguration zugegriffen werden.'; -$labels['devicetype'] = 'Gerätetyp'; -$labels['acsversion'] = 'Protokollversion'; -$labels['useragent'] = 'User Agent'; -$labels['friendlyname'] = 'Lesbarer Name'; -$labels['os'] = 'Betriebssystem'; -$labels['oslanguage'] = 'Betriebssystemsprache'; -$labels['phonenumber'] = 'Telefonnummer'; -$labels['arialabeldeviceframe'] = 'Formular für die Einstellungen zur Gerätesynchronisation'; -?> diff --git a/plugins/kolab_activesync/localization/de_DE.inc b/plugins/kolab_activesync/localization/de_DE.inc index 07de616c..aab298ed 100644 --- a/plugins/kolab_activesync/localization/de_DE.inc +++ b/plugins/kolab_activesync/localization/de_DE.inc @@ -1,10 +1,32 @@
Um ein Gerät zu registrieren, bitte zuerst nach der Anleitung von dieser Seite mit dem Server verbinden. Anschließend sollte das Gerät für die Konfiguration hier zur Verfügung stehen.'; $labels['savingdata'] = 'Daten werden gespeichert...'; +$labels['savingerror'] = 'Fehler beim Speichern der Konfiguration'; +$labels['notsupported'] = 'Ihr Server unterstützt keine Activesync-Konfiguration'; +$labels['devicedeleteconfirm'] = 'Wollen Sie wirklich alle Einstellungen für dieses Gerät löschen?'; +$labels['successfullydeleted'] = 'Die Geräteinstellungen wurden erfolgreich gelöscht'; +$labels['devicenotfound'] = 'Es kann nicht auf die Gerätekonfiguration zugegriffen werden.'; +$labels['devicetype'] = 'Gerätetyp'; +$labels['acsversion'] = 'Protokollversion'; +$labels['useragent'] = 'User Agent'; +$labels['friendlyname'] = 'Lesbarer Name'; +$labels['os'] = 'Betriebssystem'; +$labels['oslanguage'] = 'Betriebssystemsprache'; $labels['phonenumber'] = 'Telefonnummer'; -?> +$labels['arialabeldeviceframe'] = 'Formular für die Einstellungen zur Gerätesynchronisation'; diff --git a/plugins/kolab_addressbook/localization/de.inc b/plugins/kolab_addressbook/localization/de.inc deleted file mode 100644 index 51f0d770..00000000 --- a/plugins/kolab_addressbook/localization/de.inc +++ /dev/null @@ -1,66 +0,0 @@ -CardDAV-Klienten kopieren, um dasAdressbuch mit einem Computer oder mobilen Gerät zu synchronisieren.'; -$labels['addressbookprio'] = 'Reihenfolge der Adressbücher'; -$labels['personalfirst'] = 'Private(s) Adressbuch/Adressbücher zuerst'; -$labels['globalfirst'] = 'Globale(s) Adressbuch/Adressbücher zuerst'; -$labels['personalonly'] = 'Nur persönliche(s) Adressbuch/Adressbücher'; -$labels['globalonly'] = 'Nur globale(s) Adressbuch/Adressbücher'; -$labels['searchterms'] = 'Suchbegriffe'; -$labels['listsearchresults'] = 'Zusätzliche Adressbücher'; -$labels['foldersearchform'] = 'Suchformular für Adressbuch'; -$labels['foldersubscribe'] = 'Permanent anzeigen'; -$labels['nraddressbooksfound'] = '$nr Adressbücher gefunden'; -$labels['noaddressbooksfound'] = 'Keine Adressbücher gefunden'; -$labels['showhistory'] = 'Historie anzeigen'; -$labels['objectchangelog'] = 'Änderungshistorie'; -$labels['objectdiff'] = 'Änderungen aus $rev1 nach $rev2'; -$labels['revisionrestoreconfirm'] = 'Wollen Sie wirklich die Version $rev dieses Kontakt wiederherstellen? Diese Aktion wird die aktuelle Kopie mit der älteren Version ersetzen.'; -$labels['objectnotfound'] = 'Fehler beim Laden der Addressedaten'; -$labels['objectchangelognotavailable'] = 'Änderungshistorie ist nicht verfügbar für diesen Kontakt'; -$labels['objectdiffnotavailable'] = 'Vergleich für die gewählten Versionen nicht möglich'; -$labels['objectrestoresuccess'] = 'Revision $rev erfolgreich wiederhergestellt'; -$labels['objectrestoreerror'] = 'Fehler beim Wiederherstellen der alten Revision'; -$messages['bookdeleteconfirm'] = 'Soll das gewählte Adressbuch und alle Kontakte darin wirklich gelöscht werden?'; -$messages['bookdeleting'] = 'Adressbuch wird gelöscht...'; -$messages['booksaving'] = 'Adressbuch wird gespeichert...'; -$messages['bookdeleted'] = 'Adressbuch erfolgreich gelöscht.'; -$messages['bookupdated'] = 'Adressbuch erfolgreich aktualisiert.'; -$messages['bookcreated'] = 'Adressbuch erfolgreich angelegt.'; -$messages['bookdeleteerror'] = 'Fehler beim Löschen des Adressbuchs.'; -$messages['bookupdateerror'] = 'Fehler beim Aktualisieren des Adressbuchs.'; -$messages['bookcreateerror'] = 'Fehler beim Anlegen des Adressbuchs.'; -$messages['nobooknamewarning'] = 'Bitte den Namen des Adressbuchs angeben.'; -$messages['noemailnamewarning'] = 'Bitte E-Mail-Adresse oder Namen des Kontakts angeben.'; -?> diff --git a/plugins/kolab_addressbook/localization/de_DE.inc b/plugins/kolab_addressbook/localization/de_DE.inc index 0cbc4665..f119e56e 100644 --- a/plugins/kolab_addressbook/localization/de_DE.inc +++ b/plugins/kolab_addressbook/localization/de_DE.inc @@ -1,48 +1,47 @@ CardDAV-Client-Anwendung um dieses Adressbuch mit Ihrem Computer oder Mobilgerät zu synchronisieren.'; +$labels['bookname'] = 'Name des Buches'; +$labels['parentbook'] = 'Übergeordnetes Buch'; +$labels['bookshowurl'] = 'CardDAV URL anzeigen'; +$labels['carddavurldescription'] = 'Diese Adresse in einen CardDAV-Klienten kopieren, um dasAdressbuch mit einem Computer oder mobilen Gerät zu synchronisieren.'; +$labels['addressbookprio'] = 'Reihenfolge der Adressbücher'; +$labels['personalfirst'] = 'Private(s) Adressbuch/Adressbücher zuerst'; +$labels['globalfirst'] = 'Globale(s) Adressbuch/Adressbücher zuerst'; +$labels['personalonly'] = 'Nur persönliche(s) Adressbuch/Adressbücher'; +$labels['globalonly'] = 'Nur globale(s) Adressbuch/Adressbücher'; $labels['searchterms'] = 'Suchbegriffe'; $labels['listsearchresults'] = 'Zusätzliche Adressbücher'; +$labels['foldersearchform'] = 'Suchformular für Adressbuch'; +$labels['foldersubscribe'] = 'Permanent anzeigen'; $labels['nraddressbooksfound'] = '$nr Adressbücher gefunden'; $labels['noaddressbooksfound'] = 'Keine Adressbücher gefunden'; $labels['showhistory'] = 'Historie anzeigen'; $labels['objectchangelog'] = 'Änderungshistorie'; -$labels['objectdiff'] = 'Änderungen seit $rev1 bis $rev2'; -$labels['revisionrestoreconfirm'] = 'Möchten Sie wirklich den Stand $rev für diesen Kontakt wiederherstellen? Dadurch wird der aktuelle Kontakt durch die alte Version ersetzt.'; -$labels['objectchangelognotavailable'] = 'Für diesen Kontakt ist keine Änderungshistorie verfügbar'; -$labels['objectdiffnotavailable'] = 'Kein vergleich für die ausgewählten Stände möglich'; -$labels['objectrestoresuccess'] = 'Stand $rev erfolgreich wiederhergestellt'; -$labels['objectrestoreerror'] = 'Der alte Stand konnte nicht wiederhergestellt werden'; -$messages['bookdeleteconfirm'] = 'Möchten Sie das ausgewählte Adressbuch und alle darin enthaltenen Kontakte wirklich löschen?'; -$messages['bookdeleting'] = 'Adressbuch wird gelöscht...'; -$messages['booksaving'] = 'Adressbuch wird gespeichert...'; -$messages['bookdeleted'] = 'Adressbuch erfolgreich gelöscht.'; -$messages['bookupdated'] = 'Adressbuch erfolgreich aktualisiert.'; -$messages['bookcreated'] = 'Adressbuch erfolgreich angelegt.'; -$messages['bookdeleteerror'] = 'Beim Löschen des Adressbuchs ist ein Fehler aufgetreten.'; -$messages['bookupdateerror'] = 'Bei der Aktualisierung des Adressbuchs ist ein Fehler aufgetreten.'; -$messages['bookcreateerror'] = 'Beim Anlegen des Adressbuchs ist ein Fehler aufgetreten.'; -$messages['nobooknamewarning'] = 'Bitte geben Sie den Namen des Adressbuchs ein.'; -?> +$labels['objectdiff'] = 'Änderungen aus $rev1 nach $rev2'; +$labels['revisionrestoreconfirm'] = 'Wollen Sie wirklich die Version $rev dieses Kontakt wiederherstellen? Diese Aktion wird die aktuelle Kopie mit der älteren Version ersetzen.'; +$labels['objectnotfound'] = 'Fehler beim Laden der Addressedaten'; +$labels['objectchangelognotavailable'] = 'Änderungshistorie ist nicht verfügbar für diesen Kontakt'; +$labels['objectdiffnotavailable'] = 'Vergleich für die gewählten Versionen nicht möglich'; +$labels['objectrestoresuccess'] = 'Revision $rev erfolgreich wiederhergestellt'; +$labels['objectrestoreerror'] = 'Fehler beim Wiederherstellen der alten Revision'; diff --git a/plugins/kolab_auth/localization/de.inc b/plugins/kolab_auth/localization/de.inc deleted file mode 100644 index 3918e6e3..00000000 --- a/plugins/kolab_auth/localization/de.inc +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/plugins/kolab_auth/localization/de_DE.inc b/plugins/kolab_auth/localization/de_DE.inc index 8875c6bc..e92241ad 100644 --- a/plugins/kolab_auth/localization/de_DE.inc +++ b/plugins/kolab_auth/localization/de_DE.inc @@ -1,11 +1,3 @@ +$labels['loginasnotallowed'] = 'Keine Privilegien zum Anmelden als $user'; diff --git a/plugins/kolab_chat/localization/de.inc b/plugins/kolab_chat/localization/de.inc deleted file mode 100644 index 67af663f..00000000 --- a/plugins/kolab_chat/localization/de.inc +++ /dev/null @@ -1,13 +0,0 @@ - diff --git a/plugins/kolab_delegation/localization/de_DE.inc b/plugins/kolab_delegation/localization/de_DE.inc index a6789061..d04758fb 100644 --- a/plugins/kolab_delegation/localization/de_DE.inc +++ b/plugins/kolab_delegation/localization/de_DE.inc @@ -1,12 +1,8 @@ +$labels['read'] = 'Schreibgeschützt'; +$labels['write'] = 'Schreiben'; +$labels['adddelegate'] = 'Vertreter hinzufügen'; +$labels['deletedelegate'] = 'Vertreter löschen'; +$labels['savingdata'] = 'Speichere Daten...'; +$labels['delegatedeleteconfirm'] = 'Willst du wirklich diesen Vertreter löschen?'; +$labels['delegateremoveacl'] = 'Entferne Zugriffsberechtigungen auf den für diesen Benutzer zugewiesenen Ordnern.'; +$labels['deleteconfirm'] = 'Bestätigung'; +$labels['deletesuccess'] = 'Der Vertreter wurde erfolgreich entfernt'; +$labels['deleteerror'] = 'Konnte Vertreter nicht entfernen.'; +$labels['updatesuccess'] = 'Der Vertreter wurde erfolgreich aktualisiert.'; +$labels['updateerror'] = 'Konnte Verteter nicht aktualisieren'; +$labels['createsuccess'] = 'Der Vertreter wurde erfolgreich hinzugefügt'; +$labels['createerror'] = 'Konnte Vertreter nicht hinzufügen.'; +$labels['arialabeldelegatedelete'] = 'Vertreter Löschen Dialog'; +$labels['arialabeldelegateform'] = 'Verterter Eigenschaften Maske'; diff --git a/plugins/kolab_files/localization/de.inc b/plugins/kolab_files/localization/de.inc deleted file mode 100644 index 4b5ce4ab..00000000 --- a/plugins/kolab_files/localization/de.inc +++ /dev/null @@ -1,152 +0,0 @@ -$file überschreiben.'; -$labels['editfiledialog'] = 'Bearbeitungsaktion bestätigen'; -$labels['newsession'] = 'Neue Sitzung erstellen'; -$labels['ownedsession'] = 'Vorhandene Sitzung vortsetzen'; -$labels['invitedsession'] = 'Sitzung des Benutzers $user beitreten'; -$labels['editfilerotitle'] = 'Schreibgeschützte Datei'; -$labels['select'] = 'Auswählen'; -$labels['terminatesession'] = 'Sitzung beenden'; -$labels['sessionterminatedtitle'] = 'Sitzung beendet'; -$labels['terminate'] = 'Beenden'; -$labels['sessionterminating'] = 'Sitzung wird beendet …'; -$labels['participant'] = 'Teilnehmer'; -$labels['status'] = 'Status'; -$labels['addparticipant'] = 'Hinzufügen'; -$labels['delparticipant'] = 'Teilnehmer entfernen'; -$labels['invitationtextlabel'] = 'Kommentar zur Einladungs-/Benachrichtigungsnachricht'; -$labels['statusorganizer'] = 'Organisator'; -$labels['statusinvited'] = 'Eingeladen'; -$labels['statusaccepted'] = 'Angenommen'; -$labels['statusdeclined'] = 'Abgelehnt'; -$labels['statusrequested'] = 'Angefordert'; -$labels['documentinviting'] = 'Teilnehmer wird/werden eingeladen …'; -$labels['documentcancelling'] = 'Teilnehmer wird/werden entfernt …'; -$labels['removeparticipant'] = 'Entfernen'; -$labels['sessiondialog'] = 'Dokumentbearbeitungssitzung'; -$labels['more'] = 'Mehr.'; -$labels['accept'] = 'Annehmen'; -$labels['join'] = 'Der Sitzung beitreten'; -$labels['decline'] = 'Ablehnen'; -$labels['owner'] = 'Eigentümer'; -$labels['when'] = 'Wenn'; -$labels['file'] = 'Datei'; -$labels['comment'] = 'Kommentar'; -$labels['open'] = 'Öffnen'; -$labels['invitationtitle'] = 'Einladung für $file'; -$labels['invitationaccepting'] = 'Eine Einladung wird angenommen …'; -$labels['invitationdeclining'] = 'Eine Einladung wird abgelehnt …'; -$labels['invitationrequesting'] = 'Einladung wird angefordert …'; -$labels['storepasswords'] = 'Passwort merken'; -$labels['storepasswordsdesc'] = 'Gespeicherte Passwörter werden verschlüsselt. Aktivieren Sie dies, wenn Sie nicht bei jedem Login nach dem Passwort gefragt werden möchten oder wenn dieser Speicher via WebDAV verfügbar sein soll.'; -$labels['arialabelsearchform'] = 'Suchformular für Dateien'; -$labels['arialabelquicksearchbox'] = 'Sucheingabe'; -$labels['arialabellistoptions'] = 'Dateilisten Optionen'; -$labels['arialabelfolderoptions'] = 'Ordneraktionen'; -$labels['arialabelfileeditform'] = 'Dateibearbeitenformular'; -$labels['arialabelfilecreateform'] = 'Dateierstellenformular'; -$labels['arialabelfilelist'] = 'Dateiliste'; -$labels['arialabelfoldercreateform'] = 'Ordnererstellenformular'; -$labels['arialabelfoldereditform'] = 'Ordnerbearbeitenformular'; -$labels['arialabelfoldermountform'] = 'Externer-Speicherformular'; -$labels['arialabelfolderauthform'] = 'Legitimierungsformular des externen Speichers'; -$labels['arialabelfolderlist'] = 'Ordner-/Sammelauswahl'; -$labels['arialabelfileselectdialog'] = 'Dateiauswahldialog'; -$labels['arialabelattachmentoptions'] = 'Anhängespeichernoptionen'; -$labels['arialabelfilesavedialog'] = 'Datei(en)speicherndialog'; -$labels['arialabelfileprops'] = 'Dateieigenschaften'; -$labels['arialabelfilecontent'] = 'Dateiinhalt'; -$labels['arialabelfileeditdialog'] = 'Dateibearbeitungsdialog'; -$labels['arialabelfilesessiondialog'] = 'Dokumentbearbeitungssitzung'; -$labels['type.plain'] = 'Klartextdokument'; -$labels['type.vndoasisopendocumenttext'] = 'Textdokument (ODF)'; -$labels['type.html'] = 'HTML-Dokument'; diff --git a/plugins/kolab_files/localization/de_DE.inc b/plugins/kolab_files/localization/de_DE.inc index 90176ef3..21606eb9 100644 --- a/plugins/kolab_files/localization/de_DE.inc +++ b/plugins/kolab_files/localization/de_DE.inc @@ -1,34 +1,145 @@ $file überschreiben.'; +$labels['editfiledialog'] = 'Bearbeitungsaktion bestätigen'; +$labels['newsession'] = 'Neue Sitzung erstellen'; +$labels['ownedsession'] = 'Vorhandene Sitzung vortsetzen'; +$labels['invitedsession'] = 'Sitzung des Benutzers $user beitreten'; +$labels['editfilerotitle'] = 'Schreibgeschützte Datei'; $labels['select'] = 'Auswählen'; +$labels['terminatesession'] = 'Sitzung beenden'; +$labels['sessionterminatedtitle'] = 'Sitzung beendet'; +$labels['terminate'] = 'Beenden'; +$labels['sessionterminating'] = 'Sitzung wird beendet …'; $labels['participant'] = 'Teilnehmer'; $labels['status'] = 'Status'; -$labels['addparticipant'] = 'Teilnehmer hinzufügen'; +$labels['addparticipant'] = 'Hinzufügen'; +$labels['delparticipant'] = 'Teilnehmer entfernen'; +$labels['invitationtextlabel'] = 'Kommentar zur Einladungs-/Benachrichtigungsnachricht'; $labels['statusorganizer'] = 'Organisator'; -$labels['statusaccepted'] = 'Akzeptiert'; +$labels['statusinvited'] = 'Eingeladen'; +$labels['statusaccepted'] = 'Angenommen'; $labels['statusdeclined'] = 'Abgelehnt'; +$labels['statusrequested'] = 'Angefordert'; +$labels['documentinviting'] = 'Teilnehmer wird/werden eingeladen …'; +$labels['documentcancelling'] = 'Teilnehmer wird/werden entfernt …'; $labels['removeparticipant'] = 'Entfernen'; -$labels['owner'] = 'Besitzer'; +$labels['sessiondialog'] = 'Dokumentbearbeitungssitzung'; +$labels['more'] = 'Mehr.'; +$labels['accept'] = 'Annehmen'; +$labels['join'] = 'Der Sitzung beitreten'; +$labels['decline'] = 'Ablehnen'; +$labels['owner'] = 'Eigentümer'; +$labels['when'] = 'Wenn'; +$labels['file'] = 'Datei'; $labels['comment'] = 'Kommentar'; +$labels['open'] = 'Öffnen'; +$labels['invitationtitle'] = 'Einladung für $file'; +$labels['invitationaccepting'] = 'Eine Einladung wird angenommen …'; +$labels['invitationdeclining'] = 'Eine Einladung wird abgelehnt …'; +$labels['invitationrequesting'] = 'Einladung wird angefordert …'; +$labels['storepasswords'] = 'Passwort merken'; +$labels['storepasswordsdesc'] = 'Gespeicherte Passwörter werden verschlüsselt. Aktivieren Sie dies, wenn Sie nicht bei jedem Login nach dem Passwort gefragt werden möchten oder wenn dieser Speicher via WebDAV verfügbar sein soll.'; +$labels['arialabelsearchform'] = 'Suchformular für Dateien'; +$labels['arialabelquicksearchbox'] = 'Sucheingabe'; +$labels['arialabellistoptions'] = 'Dateilisten Optionen'; +$labels['arialabelfolderoptions'] = 'Ordneraktionen'; +$labels['arialabelfileeditform'] = 'Dateibearbeitenformular'; +$labels['arialabelfilecreateform'] = 'Dateierstellenformular'; +$labels['arialabelfilelist'] = 'Dateiliste'; +$labels['arialabelfoldercreateform'] = 'Ordnererstellenformular'; +$labels['arialabelfoldereditform'] = 'Ordnerbearbeitenformular'; +$labels['arialabelfoldermountform'] = 'Externer-Speicherformular'; +$labels['arialabelfolderauthform'] = 'Legitimierungsformular des externen Speichers'; +$labels['arialabelfolderlist'] = 'Ordner-/Sammelauswahl'; +$labels['arialabelfileselectdialog'] = 'Dateiauswahldialog'; +$labels['arialabelattachmentoptions'] = 'Anhängespeichernoptionen'; +$labels['arialabelfilesavedialog'] = 'Datei(en)speicherndialog'; +$labels['arialabelfileprops'] = 'Dateieigenschaften'; +$labels['arialabelfilecontent'] = 'Dateiinhalt'; +$labels['arialabelfileeditdialog'] = 'Dateibearbeitungsdialog'; +$labels['arialabelfilesessiondialog'] = 'Dokumentbearbeitungssitzung'; +$labels['type.plain'] = 'Klartextdokument'; +$labels['type.vndoasisopendocumenttext'] = 'Textdokument (ODF)'; +$labels['type.html'] = 'HTML-Dokument'; +$labels['addfolder'] = 'Ordner hinzufügen'; diff --git a/plugins/kolab_folders/localization/de.inc b/plugins/kolab_folders/localization/de.inc deleted file mode 100644 index 96a85235..00000000 --- a/plugins/kolab_folders/localization/de.inc +++ /dev/null @@ -1,30 +0,0 @@ - diff --git a/plugins/kolab_folders/localization/de_DE.inc b/plugins/kolab_folders/localization/de_DE.inc index 82470094..4a7a61d4 100644 --- a/plugins/kolab_folders/localization/de_DE.inc +++ b/plugins/kolab_folders/localization/de_DE.inc @@ -1,12 +1,5 @@ +$labels['xdays'] = '$x Tage'; diff --git a/plugins/kolab_notes/localization/de.inc b/plugins/kolab_notes/localization/de.inc deleted file mode 100644 index fbf9ef01..00000000 --- a/plugins/kolab_notes/localization/de.inc +++ /dev/null @@ -1,62 +0,0 @@ -einzelne Wiederholung einer Serie von Ereignissen'; -$labels['itipfutureoccurrence'] = 'Bezieht sich auf diese and alle zukünftigen Wiederholungen einer Serie von Ereignissen'; -$labels['itipmessagesingleoccurrence'] = 'Diese Nachricht bezieht sich nur auf eine einzelne Wiederholung'; -$labels['itipmessagefutureoccurrence'] = 'Diese Nachricht bezieht sich auf diese und alle zukünftigen Wiederholungen'; -$labels['youhaveaccepted'] = 'Sie haben die Einladung angenommen'; -$labels['youhavetentative'] = 'Sie haben die Einladung mit Vorbehalt angenommen'; -$labels['youhavedeclined'] = 'Sie haben die Einladung abgelehnt'; -$labels['youhavedelegated'] = 'Sie haben diese Einladung abgelehnt'; -$labels['youhavein-process'] = 'Sie arbeiten an dieser Aufgabe'; -$labels['youhavecompleted'] = 'Sie haben diese Aufgabe erledigt'; -$labels['youhaveneeds-action'] = 'Ihre Antwort auf diese Einladung ist noch ausstehend'; -$labels['youhavepreviouslyaccepted'] = 'Sie haben diese Einladung zuvor angenommen'; -$labels['youhavepreviouslytentative'] = 'Sie haben diese Einladung zuvor mit Vorbehalt angenommen'; -$labels['youhavepreviouslydeclined'] = 'Sie haben diese Einladung zuvor abgelehnt'; -$labels['youhavepreviouslydelegated'] = 'Sie haben diese Einladung zuvor delegiert'; -$labels['youhavepreviouslyin-process'] = 'Sie haben diese Aufgabe zuvor als In Bearbeitung gemeldet'; -$labels['youhavepreviouslycompleted'] = 'Sie haben diese Einladung zuvor erledigt'; -$labels['youhavepreviouslyneeds-action'] = 'Ihre Antwort auf diese Einladung ist noch ausstehend'; -$labels['attendeeaccepted'] = 'Teilnehmer hat akzeptiert'; -$labels['attendeetentative'] = 'Teilnehmer hat mit Vorbehalt akzeptiert'; -$labels['attendeedeclined'] = 'Teilnehmer hat abgelehnt'; -$labels['attendeedelegated'] = 'Teilnehmer hat an $delegatedto delegiert'; -$labels['attendeein-process'] = 'Teilnehmer arbeitet an dieser Aufgabe'; -$labels['attendeecompleted'] = 'Teilnehmer hat die Aufgabe erledigt'; -$labels['notanattendee'] = 'Sie sind nicht in der Liste der Teilnehmer aufgeführt'; -$labels['outdatedinvitation'] = 'Diese Einladung wurde durch eine neuere Version ersetzt'; -$labels['importtocalendar'] = 'In Kalender übernehmen'; -$labels['removefromcalendar'] = 'Aus meinem Kalender löschen'; -$labels['updatemycopy'] = 'Meine Kopie aktualisieren'; -$labels['openpreview'] = 'Vorschau öffnen'; -$labels['deleteobjectconfirm'] = 'Möchten Sie dieses Objekt wirklich löschen?'; -$labels['declinedeleteconfirm'] = 'Soll das abgelehnte Objekt ebenfalls aus Ihrem Konto gelöscht werden?'; -$labels['delegateinvitation'] = 'Einladung delegieren'; -$labels['delegateto'] = 'Delegieren an'; -$labels['delegatersvpme'] = 'Informiere mich über Aktualisierungen dieses Termins'; -$labels['delegateinvalidaddress'] = 'Geben Sie eine gültige E-Mail-Adresse für den Delegierten ein'; -$labels['savingdata'] = 'Speichere...'; -$labels['savein'] = 'Speichern in'; -$labels['expandattendeegroup'] = 'Mit Gruppenmitgliedern ersetzen'; -$labels['expandattendeegroupnodata'] = 'Diese Gruppe konnte nicht ersetzt werden. Keine Gruppenmitglieder gefunden.'; -$labels['expandattendeegrouperror'] = 'Diese Gruppe konnte nicht ersetzt werden. Sie hat möglicherweise zuviele Mitglieder.'; -$labels['expandattendeegroupsizelimit'] = 'Die Gruppe hat zuviele Mitglieder und konnte deshalb nicht ersetzt werden.'; diff --git a/plugins/libcalendaring/localization/de_DE.inc b/plugins/libcalendaring/localization/de_DE.inc index 14f6504c..45a93095 100644 --- a/plugins/libcalendaring/localization/de_DE.inc +++ b/plugins/libcalendaring/localization/de_DE.inc @@ -1,89 +1,155 @@ einzelne Wiederholung einer Serie von Ereignissen'; +$labels['itipfutureoccurrence'] = 'Bezieht sich auf diese and alle zukünftigen Wiederholungen einer Serie von Ereignissen'; +$labels['itipmessagesingleoccurrence'] = 'Diese Nachricht bezieht sich nur auf eine einzelne Wiederholung'; +$labels['itipmessagefutureoccurrence'] = 'Diese Nachricht bezieht sich auf diese und alle zukünftigen Wiederholungen'; +$labels['youhaveaccepted'] = 'Sie haben die Einladung angenommen'; +$labels['youhavetentative'] = 'Sie haben die Einladung mit Vorbehalt angenommen'; +$labels['youhavedeclined'] = 'Sie haben die Einladung abgelehnt'; +$labels['youhavedelegated'] = 'Sie haben diese Einladung abgelehnt'; +$labels['youhavein-process'] = 'Sie arbeiten an dieser Aufgabe'; +$labels['youhavecompleted'] = 'Sie haben diese Aufgabe erledigt'; +$labels['youhaveneeds-action'] = 'Ihre Antwort auf diese Einladung ist noch ausstehend'; +$labels['youhavepreviouslyaccepted'] = 'Sie haben diese Einladung zuvor angenommen'; +$labels['youhavepreviouslytentative'] = 'Sie haben diese Einladung zuvor mit Vorbehalt angenommen'; +$labels['youhavepreviouslydeclined'] = 'Sie haben diese Einladung zuvor abgelehnt'; +$labels['youhavepreviouslydelegated'] = 'Sie haben diese Einladung zuvor delegiert'; +$labels['youhavepreviouslyin-process'] = 'Sie haben diese Aufgabe zuvor als In Bearbeitung gemeldet'; +$labels['youhavepreviouslycompleted'] = 'Sie haben diese Einladung zuvor erledigt'; +$labels['youhavepreviouslyneeds-action'] = 'Ihre Antwort auf diese Einladung ist noch ausstehend'; +$labels['attendeeaccepted'] = 'Teilnehmer hat akzeptiert'; +$labels['attendeetentative'] = 'Teilnehmer hat mit Vorbehalt akzeptiert'; +$labels['attendeedeclined'] = 'Teilnehmer hat abgelehnt'; +$labels['attendeedelegated'] = 'Teilnehmer hat an $delegatedto delegiert'; +$labels['attendeein-process'] = 'Teilnehmer arbeitet an dieser Aufgabe'; +$labels['attendeecompleted'] = 'Teilnehmer hat die Aufgabe erledigt'; +$labels['notanattendee'] = 'Sie sind nicht in der Liste der Teilnehmer aufgeführt'; +$labels['outdatedinvitation'] = 'Diese Einladung wurde durch eine neuere Version ersetzt'; +$labels['importtocalendar'] = 'In Kalender übernehmen'; +$labels['removefromcalendar'] = 'Aus meinem Kalender löschen'; +$labels['updatemycopy'] = 'Meine Kopie aktualisieren'; +$labels['openpreview'] = 'Vorschau öffnen'; +$labels['deleteobjectconfirm'] = 'Möchten Sie dieses Objekt wirklich löschen?'; +$labels['declinedeleteconfirm'] = 'Soll das abgelehnte Objekt ebenfalls aus Ihrem Konto gelöscht werden?'; +$labels['delegateinvitation'] = 'Einladung delegieren'; +$labels['delegateto'] = 'Delegieren an'; +$labels['delegatersvpme'] = 'Informiere mich über Aktualisierungen dieses Termins'; +$labels['delegateinvalidaddress'] = 'Geben Sie eine gültige E-Mail-Adresse für den Delegierten ein'; +$labels['savingdata'] = 'Speichere...'; +$labels['savein'] = 'Speichern in'; +$labels['expandattendeegroup'] = 'Mit Gruppenmitgliedern ersetzen'; +$labels['expandattendeegroupnodata'] = 'Diese Gruppe konnte nicht ersetzt werden. Keine Gruppenmitglieder gefunden.'; +$labels['expandattendeegrouperror'] = 'Diese Gruppe konnte nicht ersetzt werden. Sie hat möglicherweise zuviele Mitglieder.'; +$labels['expandattendeegroupsizelimit'] = 'Die Gruppe hat zuviele Mitglieder und konnte deshalb nicht ersetzt werden.'; diff --git a/plugins/libkolab/localization/de.inc b/plugins/libkolab/localization/de.inc deleted file mode 100644 index 1a9af0e5..00000000 --- a/plugins/libkolab/localization/de.inc +++ /dev/null @@ -1,25 +0,0 @@ -CalDAV Client-Anwendung (z.B. Evolution oder Mozilla Thunderbird), um diese spezifische Aufgabenliste mit Ihrem Computer oder Mobilgerät zu synchronisieren.'; -$labels['newtask'] = 'Neue Aufgabe'; -$labels['createtask'] = 'Aufgabe erstellen '; -$labels['createnewtask'] = 'Neue Aufgabe erstellen (z.B. Samstag, Rasen mähen)'; -$labels['createfrommail'] = 'Aufgabe speichern'; -$labels['printtitle'] = 'Aufgaben drucken'; -$labels['printdescriptions'] = 'Beschreibungen drucken'; -$labels['mark'] = 'Markieren'; -$labels['unmark'] = 'Markierung entfernen'; -$labels['edit'] = 'Bearbeiten'; -$labels['delete'] = 'Löschen'; -$labels['title'] = 'Titel'; -$labels['description'] = 'Beschreibung'; -$labels['datetime'] = 'Fällig'; -$labels['duetime'] = 'Fällig'; -$labels['start'] = 'Beginn'; -$labels['starttime'] = 'Startzeit'; -$labels['alarms'] = 'Erinnerung'; -$labels['repeat'] = 'Wiederholung'; -$labels['links'] = 'Referenz'; -$labels['status'] = 'Status'; -$labels['status-needs-action'] = 'Braucht Aktion'; -$labels['status-in-process'] = 'In Bearbeitung'; -$labels['status-completed'] = 'Abgeschlossen'; -$labels['status-cancelled'] = 'Abgesagt'; -$labels['assignedto'] = 'Zugewiesen an'; -$labels['created'] = 'Erstellt'; -$labels['changed'] = 'Zuletzt geändert'; -$labels['taskoptions'] = 'Optionen'; -$labels['all'] = 'Alle'; -$labels['flagged'] = 'Markiert'; -$labels['complete'] = 'Abgeschlossen'; -$labels['completeness'] = 'Fortschritt'; -$labels['overdue'] = 'Überfällig'; -$labels['today'] = 'Heute'; -$labels['tomorrow'] = 'Morgen'; -$labels['next7days'] = 'Innerhalb von 7 Tagen'; -$labels['later'] = 'Später'; -$labels['assigned'] = 'Zugewiesen'; -$labels['assignedtitle'] = 'Aufgaben, welche an andere vergeben wurden'; -$labels['mytasks'] = 'Meine Aufgaben'; -$labels['mytaskstitle'] = 'An mich übertragene Aufgaben'; -$labels['nodate'] = 'Ohne Datum'; -$labels['removetag'] = 'Entfernen'; -$labels['removelink'] = 'E-Mail-Referenz entfernen'; -$labels['auto'] = 'Automatisch'; -$labels['newtask'] = 'Neue Aufgabe'; -$labels['edittask'] = 'Aufgabe ändern'; -$labels['save'] = 'Speichern'; -$labels['cancel'] = 'Abbrechen'; -$labels['saveandnotify'] = 'Speichern und Benachrichtigen'; -$labels['addsubtask'] = 'Teilaufgabe hinzufügen'; -$labels['deletetask'] = 'Aufgabe löschen'; -$labels['deletethisonly'] = 'Nur diese Aufgabe löschen'; -$labels['deletewithchilds'] = 'Mit allen Teilaufgaben löschen'; -$labels['taskactions'] = 'Aufgabeneinstellungen...'; -$labels['tabsummary'] = 'Titel'; -$labels['tabrecurrence'] = 'Wiederholung'; -$labels['tabassignments'] = 'Zuweisungen'; -$labels['tabattachments'] = 'Anhänge'; -$labels['tabsharing'] = 'Freigabe'; -$labels['editlist'] = 'Liste bearbeiten'; -$labels['createlist'] = 'Liste hinzufügen'; -$labels['listactions'] = 'Listeneinstellungen…'; -$labels['listname'] = 'Name'; -$labels['showalarms'] = 'Erinnerungen anzeigen'; -$labels['import'] = 'Importieren'; -$labels['viewactions'] = 'Ansicht-Aktionen'; -$labels['focusview'] = 'Nur diese Liste anzeigen'; -$labels['on'] = 'am'; -$labels['at'] = 'um'; -$labels['this'] = 'dies'; -$labels['next'] = 'weiter'; -$labels['yes'] = 'Ja'; -$labels['savingdata'] = 'Daten werden gespeichert…'; -$labels['errorsaving'] = 'Daten konnten nicht gespeichert werden.'; -$labels['notasksfound'] = 'Keine Aufgabe erfüllt die angelegten Kriterien'; -$labels['invalidstartduedates'] = 'Das Anfangsdatum muss vor dem Fälligkeitsdatum liegen.'; -$labels['invalidstartduetimes'] = 'Start- und Enddatum müssen entweder beide oder keins eine Zeit enthalten.'; -$labels['recurrencerequiresdate'] = 'Wiederkehrende Aufgaben erfordern entweder ein Start- oder Enddatum.'; -$labels['deletetasktconfirm'] = 'Diese Aufgabe wirklich löschen?'; -$labels['deleteparenttasktconfirm'] = 'Diese Aufgabe wirklich mit allen Teilaufgaben löschen?'; -$labels['deletelistconfirm'] = 'Diese Aufgabenliste wirklich mit allen Aufgaben löschen?'; -$labels['deletelistconfirmrecursive'] = 'Soll diese Liste wirklich mit allen Aufgaben und Unterlisten gelöscht werden?'; -$labels['aclnorights'] = 'Der Zugriff auf diese Aufgabenliste erfordert Administrator-Rechte.'; -$labels['changetaskconfirm'] = 'Aufgabe ändern'; -$labels['changeconfirmnotifications'] = 'Wollen Sie die beauftragten Teilnehmer über diese Änderung informieren?'; -$labels['partstatupdatenotification'] = 'Wollen Sie den Organisator über die Statusänderung benachrichtigen?'; -$labels['quickaddinput'] = 'Neue Aufgabe Datum und Titel'; -$labels['arialabelquickaddbox'] = 'Neue Aufgabe schnell hinzufügen'; -$labels['arialabelsearchform'] = 'Suchformular für Aufgaben'; -$labels['arialabelquicksearchbox'] = 'Sucheingabe für Aufgaben'; -$labels['arialabellistsearchform'] = 'Sucheingabe für Aufgabenlisten'; -$labels['arialabeltaskselector'] = 'Listenmodus'; -$labels['arialabeltasklisting'] = 'Aufgabenauflistung'; -$labels['arialabelsortmenu'] = 'Aufgaben-Sortierungsoptionen'; -$labels['attendee'] = 'Beauftragter'; -$labels['role'] = 'Rolle'; -$labels['availability'] = 'Verfüg.'; -$labels['confirmstate'] = 'Status'; -$labels['addattendee'] = 'Beauftragten hinzufügen'; -$labels['roleorganizer'] = 'Organisator'; -$labels['rolerequired'] = 'Erforderlich'; -$labels['roleoptional'] = 'Optional'; -$labels['rolechair'] = 'Vorsitz'; -$labels['rolenonparticipant'] = 'Beobachter'; -$labels['sendinvitations'] = 'Einladungen versenden'; -$labels['sendnotifications'] = 'Beauftragte Teilnehmer über die Änderung informieren'; -$labels['sendcancellation'] = 'Beauftragte Teilnehmer über die Stornierung informieren'; -$labels['invitationsubject'] = 'Ihnen wurde "$title" zugewiesen'; -$labels['invitationmailbody'] = "*\$title*\n\nFällig: \$date\n\nTeilnehmer: \$attendees\n\n\$description\n\nAngehängt finden Sie eine iCalendar-Datei mit allen Aufgabendetails, welche in Ihre Aufgabenanwendung importiert werden kann."; -$labels['itipupdatesubject'] = '"$title" wurde aktualisiert'; -$labels['itipupdatesubjectempty'] = 'Eine ihrer Aufgabe wurde aktualisiert'; -$labels['itipupdatemailbody'] = "*\$title*\n\nFällig: \$date\n\nTeilnehmer: \$attendees\n\nAngehängt finden Sie eine iCalendar-Datei mit den aktualisierten Aufgabendetails, welche in Ihre Aufgabenanwendung importiert werden kann."; -$labels['itipcancelsubject'] = '"$title" wurde abgesagt'; -$labels['itipcancelmailbody'] = "*\$title*\n\nFällig: \$date\n\nTeilnehmer: \$attendees\n\nDie Aufgabe wurde durch \$organizer storniert.\n\nAngehängt finden Sie eine iCalendar-Datei mit den aktualisierten Aufgabendetails."; -$labels['saveintasklist'] = 'speichern in'; -$labels['taskhistory'] = 'Historie'; -$labels['objectchangelog'] = 'Änderungshistorie'; -$labels['objectdiff'] = 'Änderungen aus $rev1 nach $rev2'; -$labels['objectnotfound'] = 'Fehler beim Laden der Aufgabendaten'; -$labels['objectchangelognotavailable'] = 'Änderung der Historie ist nicht verfügbar für diese Aufgabe.'; -$labels['objectdiffnotavailable'] = 'Vergleich für die gewählten Versionen nicht möglich'; -$labels['revisionrestoreconfirm'] = 'Möchten Sie wirklich die Version $rev dieser Aufgabe wiederherstellen? Dies wird die aktuelle Aufgabe mit der alten Version ersetzen.'; -$labels['objectrestoresuccess'] = 'Revision $rev erfolgreich wiederhergestellt'; -$labels['objectrestoreerror'] = 'Fehler beim Wiederherstellen der alten Revision'; -$labels['itipobjectnotfound'] = 'Die Aufgabe, auf welche sich diese Nachricht bezieht, wurde nicht in Ihrer Aufgabenliste gefunden.'; -$labels['itipmailbodyaccepted'] = "\$sender hat die Zuweisung folgender Aufgabe akzeptiert:\n\n*\$title*\n\nFällig: \$date\n\nVerantwortlich: \$attendees"; -$labels['itipmailbodytentative'] = "\$sender hat die Zuweisung folgender Aufgabe unter Vorbehalt akzeptiert:\n\n*\$title*\n\nFällig: \$date\n\nVerantwortlich: \$attendees"; -$labels['itipmailbodydeclined'] = "\$sender hat die Zuweisung folgender Aufgabe abgeleht:\n\n*\$title*\n\nFällig: \$date\n\nVerantwortlich: \$attendees"; -$labels['itipmailbodycancel'] = "\$sender hat die Zuweisung folgender Aufgabe abgeleht:\n\n*\$title*\n\nFällig: \$date"; -$labels['itipmailbodyin-process'] = "\$sender hat den Status folgender Aufgabe auf in-Bearbeitung gesetzt:\n\n*\$title*\n\nFällig: \$date"; -$labels['itipmailbodycompleted'] = "\$sender hat folgende Aufgabe abgeschlossen:\n\n*\$title*\n\nFällig: \$date"; -$labels['itipmailbodydelegated'] = "\$sender hat folgende Aufgabe delegiert:\n\n*\$title*\n\nFällig: \$date"; -$labels['itipmailbodydelegatedto'] = "\$sender hat folgende Aufgabe an Sie delegiert:\n\n*\$title*\n\nFällig: \$date"; -$labels['attendeeaccepted'] = 'Delegierter hat akzeptiert'; -$labels['attendeetentative'] = 'Delegierter hat unter Vorbehalt akzeptiert'; -$labels['attendeedeclined'] = 'Delegierter hat abgelehnt'; -$labels['attendeedelegated'] = 'Zugewiesener hat zu $delegatedto delegiert'; -$labels['attendeein-process'] = 'Delegierter ist in Bearbeitung '; -$labels['attendeecompleted'] = 'Delegierter hat abgeschlossen'; -$labels['acceptinvitation'] = 'Akzeptieren Sie die Zuweisung?'; -$labels['itipdeclinetask'] = 'Lehnen Sie to Zuweisung dieser Aufgabe ab'; -$labels['declinedeleteconfirm'] = 'Möchten Sie diese abgelehnete Aufgabe aus Ihrer Aufgabenliste löschen?'; -$labels['itipcomment'] = 'Kommentar zur Einladungs-/Benachrichtigungsnachricht'; -$labels['itipcommenttitle'] = 'Dieser Kommentar wird der Benachrichtigung an andere Delegierte hinzugefügt'; -$labels['itipsendsuccess'] = 'Benachrichtigung an Delegierte gesendet'; -$labels['errornotifying'] = 'Senden der Benachrichtigung an Delegierte fehlgeschlagen'; -$labels['removefromcalendar'] = 'Aus meinen Aufgaben entfernen'; -$labels['delegateinvitation'] = 'Zuweisung delegieren'; -$labels['andnmore'] = '$nr weitere...'; -$labels['savetotasklist'] = 'In den Aufgaben speichern'; -$labels['comment'] = 'Kommentar'; -$labels['rsvpcomment'] = 'Kommentar'; -$labels['errorimportingtask'] = 'Fehler beim Importieren der Aufgabe(n)'; -$labels['importwarningexists'] = 'Eine Kopie dieser Aufgabe exisistiert bereits in Ihrer Aufgabenliste'; -$labels['importsuccess'] = '$nr Aufgaben erfolgreich importiert'; -$labels['importerror'] = 'Fehler beim Importieren'; -$labels['newerversionexists'] = 'Eine neuere Version dieser Aufgabe existiert bereits! Abbruch.'; -$labels['nowritetasklistfound'] = 'Keine Aufgabenliste zum Speichern der Aufgabe gefunden'; -$labels['importedsuccessfully'] = 'Die Aufgabe wurde erfolgreich unter \'$list\' gespeichert'; -$labels['updatedsuccessfully'] = 'Die Aufgabe wurde erfolgreich in \'$list\' aktualisiert'; -$labels['attendeupdateesuccess'] = 'Teilnehmerstatus erfolgreich aktualisiert'; -$labels['itipresponseerror'] = 'Senden der Antwort auf diese Aufgabenzuweisung fehlgeschlagen'; -$labels['itipinvalidrequest'] = 'Diese Einladung ist nicht mehr gültig.'; -$labels['sentresponseto'] = 'Antwort auf Aufgabenzuweisung erfolgreich an $mailto versendet'; -$labels['successremoval'] = 'Diese Aufgabe wurde erfolgreich gelöscht.'; -$labels['invalidlistproperties'] = 'Ungültige Listeneigenschaften! Bitte einen gültigen Namen eingeben.'; diff --git a/plugins/tasklist/localization/de_DE.inc b/plugins/tasklist/localization/de_DE.inc index 4ecccc01..65d7e644 100644 --- a/plugins/tasklist/localization/de_DE.inc +++ b/plugins/tasklist/localization/de_DE.inc @@ -1,86 +1,244 @@ CalDAV-Client-Anwendung (z.B. Evolution oder Mozilla Thunderbird) um diese Aufgabenliste mit Ihrem Computer oder Mobilgerät zu synchronisieren.'; +$labels['removelist'] = 'Von der Liste entfernen'; +$labels['showcaldavurl'] = 'CalDAV URL anzeigen'; +$labels['caldavurldescription'] = 'Kopieren dieser Adresse in eine CalDAV Client-Anwendung (z.B. Evolution oder Mozilla Thunderbird), um diese spezifische Aufgabenliste mit Ihrem Computer oder Mobilgerät zu synchronisieren.'; $labels['newtask'] = 'Neue Aufgabe'; $labels['createtask'] = 'Aufgabe erstellen '; $labels['createnewtask'] = 'Neue Aufgabe erstellen (z.B. Samstag, Rasen mähen)'; -$labels['createfrommail'] = 'Als Aufgabe speichern'; +$labels['createfrommail'] = 'Aufgabe speichern'; $labels['printtitle'] = 'Aufgaben drucken'; +$labels['printdescriptions'] = 'Beschreibungen drucken'; +$labels['mark'] = 'Markieren'; +$labels['unmark'] = 'Markierung entfernen'; $labels['edit'] = 'Bearbeiten'; $labels['delete'] = 'Löschen'; $labels['title'] = 'Titel'; $labels['description'] = 'Beschreibung'; -$labels['start'] = 'Start'; -$labels['starttime'] = 'Beginn'; +$labels['datetime'] = 'Fällig'; +$labels['duetime'] = 'Fällig'; +$labels['start'] = 'Beginn'; +$labels['starttime'] = 'Startzeit'; $labels['alarms'] = 'Erinnerung'; -$labels['repeat'] = 'Wiederholen'; +$labels['repeat'] = 'Wiederholung'; +$labels['links'] = 'Referenz'; $labels['status'] = 'Status'; -$labels['status-needs-action'] = 'Bearbeitung erforderlich'; +$labels['status-needs-action'] = 'Braucht Aktion'; +$labels['status-in-process'] = 'In Bearbeitung'; $labels['status-completed'] = 'Abgeschlossen'; -$labels['status-cancelled'] = 'Gekündigt'; +$labels['status-cancelled'] = 'Abgesagt'; $labels['assignedto'] = 'Zugewiesen an'; $labels['created'] = 'Erstellt'; -$labels['changed'] = 'Zuletzt bearbeitet'; +$labels['changed'] = 'Zuletzt geändert'; $labels['taskoptions'] = 'Optionen'; $labels['all'] = 'Alle'; -$labels['complete'] = 'Erledigt'; +$labels['flagged'] = 'Markiert'; +$labels['complete'] = 'Abgeschlossen'; $labels['completeness'] = 'Fortschritt'; $labels['overdue'] = 'Überfällig'; $labels['today'] = 'Heute'; $labels['tomorrow'] = 'Morgen'; -$labels['next7days'] = 'Nächste 7 Tage'; +$labels['next7days'] = 'Innerhalb von 7 Tagen'; $labels['later'] = 'Später'; -$labels['assignedtitle'] = 'Aufgaben die Sie anderen Personen zugewiesen haben'; +$labels['assigned'] = 'Zugewiesen'; +$labels['assignedtitle'] = 'Aufgaben, welche an andere vergeben wurden'; $labels['mytasks'] = 'Meine Aufgaben'; -$labels['mytaskstitle'] = 'Mir zugewiesene Aufgaben'; -$labels['nodate'] = 'kein Datum'; +$labels['mytaskstitle'] = 'An mich übertragene Aufgaben'; +$labels['nodate'] = 'Ohne Datum'; $labels['removetag'] = 'Entfernen'; -$labels['newtask'] = 'Neue Aufgabe'; -$labels['edittask'] = 'Aufgabe bearbeiten'; +$labels['removelink'] = 'E-Mail-Referenz entfernen'; +$labels['auto'] = 'Automatisch'; +$labels['edittask'] = 'Aufgabe ändern'; $labels['save'] = 'Speichern'; $labels['cancel'] = 'Abbrechen'; -$labels['addsubtask'] = 'Unteraufgabe hinzufügen'; -$labels['tabsummary'] = 'Zusammenfassung'; +$labels['saveandnotify'] = 'Speichern und Benachrichtigen'; +$labels['addsubtask'] = 'Teilaufgabe hinzufügen'; +$labels['deletetask'] = 'Aufgabe löschen'; +$labels['deletethisonly'] = 'Nur diese Aufgabe löschen'; +$labels['deletewithchilds'] = 'Mit allen Teilaufgaben löschen'; +$labels['taskactions'] = 'Aufgabeneinstellungen...'; +$labels['tabsummary'] = 'Titel'; $labels['tabrecurrence'] = 'Wiederholung'; +$labels['tabassignments'] = 'Zuweisungen'; $labels['tabattachments'] = 'Anhänge'; +$labels['tabsharing'] = 'Freigabe'; +$labels['editlist'] = 'Liste bearbeiten'; +$labels['createlist'] = 'Liste hinzufügen'; +$labels['listactions'] = 'Listeneinstellungen…'; $labels['listname'] = 'Name'; -$labels['at'] = 'am'; +$labels['showalarms'] = 'Erinnerungen anzeigen'; +$labels['import'] = 'Importieren'; +$labels['viewactions'] = 'Ansicht-Aktionen'; +$labels['focusview'] = 'Nur diese Liste anzeigen'; +$labels['on'] = 'am'; +$labels['at'] = 'um'; +$labels['this'] = 'dies'; +$labels['next'] = 'weiter'; $labels['yes'] = 'Ja'; -$labels['savingdata'] = 'Daten werden gespeichert...'; +$labels['savingdata'] = 'Daten werden gespeichert…'; +$labels['errorsaving'] = 'Daten konnten nicht gespeichert werden.'; +$labels['notasksfound'] = 'Keine Aufgabe erfüllt die angelegten Kriterien'; +$labels['invalidstartduedates'] = 'Das Anfangsdatum muss vor dem Fälligkeitsdatum liegen.'; +$labels['invalidstartduetimes'] = 'Start- und Enddatum müssen entweder beide oder keins eine Zeit enthalten.'; +$labels['recurrencerequiresdate'] = 'Wiederkehrende Aufgaben erfordern entweder ein Start- oder Enddatum.'; +$labels['deletetasktconfirm'] = 'Diese Aufgabe wirklich löschen?'; +$labels['deleteparenttasktconfirm'] = 'Diese Aufgabe wirklich mit allen Teilaufgaben löschen?'; +$labels['deletelistconfirm'] = 'Diese Aufgabenliste wirklich mit allen Aufgaben löschen?'; +$labels['deletelistconfirmrecursive'] = 'Soll diese Liste wirklich mit allen Aufgaben und Unterlisten gelöscht werden?'; +$labels['aclnorights'] = 'Der Zugriff auf diese Aufgabenliste erfordert Administrator-Rechte.'; +$labels['changetaskconfirm'] = 'Aufgabe ändern'; +$labels['changeconfirmnotifications'] = 'Wollen Sie die beauftragten Teilnehmer über diese Änderung informieren?'; +$labels['partstatupdatenotification'] = 'Wollen Sie den Organisator über die Statusänderung benachrichtigen?'; +$labels['quickaddinput'] = 'Neue Aufgabe Datum und Titel'; +$labels['arialabelquickaddbox'] = 'Neue Aufgabe schnell hinzufügen'; +$labels['arialabelsearchform'] = 'Suchformular für Aufgaben'; +$labels['arialabelquicksearchbox'] = 'Sucheingabe für Aufgaben'; +$labels['arialabellistsearchform'] = 'Sucheingabe für Aufgabenlisten'; +$labels['arialabeltaskselector'] = 'Listenmodus'; +$labels['arialabeltasklisting'] = 'Aufgabenauflistung'; +$labels['arialabelsortmenu'] = 'Aufgaben-Sortierungsoptionen'; +$labels['attendee'] = 'Beauftragter'; +$labels['role'] = 'Rolle'; +$labels['availability'] = 'Verfüg.'; $labels['confirmstate'] = 'Status'; +$labels['addattendee'] = 'Beauftragten hinzufügen'; $labels['roleorganizer'] = 'Organisator'; -$labels['rolerequired'] = 'Pflichtfeld'; +$labels['rolerequired'] = 'Erforderlich'; $labels['roleoptional'] = 'Optional'; -$labels['rolechair'] = 'Vorsitzender'; +$labels['rolechair'] = 'Vorsitz'; +$labels['rolenonparticipant'] = 'Beobachter'; +$labels['sendinvitations'] = 'Einladungen versenden'; +$labels['sendnotifications'] = 'Beauftragte Teilnehmer über die Änderung informieren'; +$labels['sendcancellation'] = 'Beauftragte Teilnehmer über die Stornierung informieren'; +$labels['invitationsubject'] = 'Ihnen wurde "$title" zugewiesen'; +$labels['invitationmailbody'] = '*$title* + +Fällig: $date + +Teilnehmer: $attendees + +$description + +Angehängt finden Sie eine iCalendar-Datei mit allen Aufgabendetails, welche in Ihre Aufgabenanwendung importiert werden kann.'; $labels['itipupdatesubject'] = '"$title" wurde aktualisiert'; +$labels['itipupdatesubjectempty'] = 'Eine ihrer Aufgabe wurde aktualisiert'; +$labels['itipupdatemailbody'] = '*$title* + +Fällig: $date + +Teilnehmer: $attendees + +Angehängt finden Sie eine iCalendar-Datei mit den aktualisierten Aufgabendetails, welche in Ihre Aufgabenanwendung importiert werden kann.'; $labels['itipcancelsubject'] = '"$title" wurde abgesagt'; +$labels['itipcancelmailbody'] = '*$title* + +Fällig: $date + +Teilnehmer: $attendees + +Die Aufgabe wurde durch $organizer storniert. + +Angehängt finden Sie eine iCalendar-Datei mit den aktualisierten Aufgabendetails.'; +$labels['saveintasklist'] = 'speichern in'; $labels['taskhistory'] = 'Historie'; $labels['objectchangelog'] = 'Änderungshistorie'; -$labels['objectdiff'] = 'Änderungen seit $rev1 bis $rev2'; -$labels['objectdiffnotavailable'] = 'Kein vergleich für die ausgewählten Stände möglich'; -$labels['objectrestoresuccess'] = 'Stand $rev erfolgreich wiederhergestellt'; -$labels['objectrestoreerror'] = 'Der alte Stand konnte nicht wiederhergestellt werden'; -$labels['andnmore'] = '$nr mehr...'; +$labels['objectdiff'] = 'Änderungen aus $rev1 nach $rev2'; +$labels['objectnotfound'] = 'Fehler beim Laden der Aufgabendaten'; +$labels['objectchangelognotavailable'] = 'Änderung der Historie ist nicht verfügbar für diese Aufgabe.'; +$labels['objectdiffnotavailable'] = 'Vergleich für die gewählten Versionen nicht möglich'; +$labels['revisionrestoreconfirm'] = 'Möchten Sie wirklich die Version $rev dieser Aufgabe wiederherstellen? Dies wird die aktuelle Aufgabe mit der alten Version ersetzen.'; +$labels['objectrestoresuccess'] = 'Revision $rev erfolgreich wiederhergestellt'; +$labels['objectrestoreerror'] = 'Fehler beim Wiederherstellen der alten Revision'; +$labels['itipobjectnotfound'] = 'Die Aufgabe, auf welche sich diese Nachricht bezieht, wurde nicht in Ihrer Aufgabenliste gefunden.'; +$labels['itipmailbodyaccepted'] = '$sender hat die Zuweisung folgender Aufgabe akzeptiert: + +*$title* + +Fällig: $date + +Verantwortlich: $attendees'; +$labels['itipmailbodytentative'] = '$sender hat die Zuweisung folgender Aufgabe unter Vorbehalt akzeptiert: + +*$title* + +Fällig: $date + +Verantwortlich: $attendees'; +$labels['itipmailbodydeclined'] = '$sender hat die Zuweisung folgender Aufgabe abgeleht: + +*$title* + +Fällig: $date + +Verantwortlich: $attendees'; +$labels['itipmailbodycancel'] = '$sender hat die Zuweisung folgender Aufgabe abgeleht: + +*$title* + +Fällig: $date'; +$labels['itipmailbodyin-process'] = '$sender hat den Status folgender Aufgabe auf in-Bearbeitung gesetzt: + +*$title* + +Fällig: $date'; +$labels['itipmailbodycompleted'] = '$sender hat folgende Aufgabe abgeschlossen: + +*$title* + +Fällig: $date'; +$labels['itipmailbodydelegated'] = '$sender hat folgende Aufgabe delegiert: + +*$title* + +Fällig: $date'; +$labels['itipmailbodydelegatedto'] = '$sender hat folgende Aufgabe an Sie delegiert: + +*$title* + +Fällig: $date'; +$labels['attendeeaccepted'] = 'Delegierter hat akzeptiert'; +$labels['attendeetentative'] = 'Delegierter hat unter Vorbehalt akzeptiert'; +$labels['attendeedeclined'] = 'Delegierter hat abgelehnt'; +$labels['attendeedelegated'] = 'Zugewiesener hat zu $delegatedto delegiert'; +$labels['attendeein-process'] = 'Delegierter ist in Bearbeitung '; +$labels['attendeecompleted'] = 'Delegierter hat abgeschlossen'; +$labels['acceptinvitation'] = 'Akzeptieren Sie die Zuweisung?'; +$labels['itipdeclinetask'] = 'Lehnen Sie to Zuweisung dieser Aufgabe ab'; +$labels['declinedeleteconfirm'] = 'Möchten Sie diese abgelehnete Aufgabe aus Ihrer Aufgabenliste löschen?'; +$labels['itipcomment'] = 'Kommentar zur Einladungs-/Benachrichtigungsnachricht'; +$labels['itipcommenttitle'] = 'Dieser Kommentar wird der Benachrichtigung an andere Delegierte hinzugefügt'; +$labels['itipsendsuccess'] = 'Benachrichtigung an Delegierte gesendet'; +$labels['errornotifying'] = 'Senden der Benachrichtigung an Delegierte fehlgeschlagen'; +$labels['removefromcalendar'] = 'Aus meinen Aufgaben entfernen'; +$labels['delegateinvitation'] = 'Zuweisung delegieren'; +$labels['andnmore'] = '$nr weitere...'; +$labels['savetotasklist'] = 'In den Aufgaben speichern'; $labels['comment'] = 'Kommentar'; $labels['rsvpcomment'] = 'Kommentar'; -$labels['itipinvalidrequest'] = 'Die Einladung ist nicht länger gültig'; +$labels['errorimportingtask'] = 'Fehler beim Importieren der Aufgabe(n)'; +$labels['importwarningexists'] = 'Eine Kopie dieser Aufgabe exisistiert bereits in Ihrer Aufgabenliste'; +$labels['importsuccess'] = '$nr Aufgaben erfolgreich importiert'; +$labels['importerror'] = 'Fehler beim Importieren'; +$labels['newerversionexists'] = 'Eine neuere Version dieser Aufgabe existiert bereits! Abbruch.'; +$labels['nowritetasklistfound'] = 'Keine Aufgabenliste zum Speichern der Aufgabe gefunden'; +$labels['importedsuccessfully'] = 'Die Aufgabe wurde erfolgreich unter '$list' gespeichert'; +$labels['updatedsuccessfully'] = 'Die Aufgabe wurde erfolgreich in '$list' aktualisiert'; +$labels['attendeupdateesuccess'] = 'Teilnehmerstatus erfolgreich aktualisiert'; +$labels['itipresponseerror'] = 'Senden der Antwort auf diese Aufgabenzuweisung fehlgeschlagen'; +$labels['itipinvalidrequest'] = 'Diese Einladung ist nicht mehr gültig.'; +$labels['sentresponseto'] = 'Antwort auf Aufgabenzuweisung erfolgreich an $mailto versendet'; +$labels['successremoval'] = 'Diese Aufgabe wurde erfolgreich gelöscht.'; +$labels['invalidlistproperties'] = 'Ungültige Listeneigenschaften! Bitte einen gültigen Namen eingeben.'; From 618fbe9b359ddae57afb9797e7b683ab875965d6 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Fri, 28 Dec 2018 13:08:17 +0100 Subject: [PATCH 06/98] Fix logon_page in Elastic (and Elastic-based) skins (Bifrost#T168440) --- plugins/logon_page/logon_page.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/logon_page/logon_page.php b/plugins/logon_page/logon_page.php index 4247a36e..6e00a15a 100644 --- a/plugins/logon_page/logon_page.php +++ b/plugins/logon_page/logon_page.php @@ -51,6 +51,7 @@ class logon_page extends rcube_plugin if (file_exists($file)) { $html = file_get_contents($file); + $html = trim(str_replace('', '', $html)); } if ($html) { @@ -63,6 +64,9 @@ class logon_page extends rcube_plugin // so it can be styled by skins $html = '
' . $html . '
'; + // In Elastic we have to move the element to more apropriate place + $html .= ""; + // Add the content at the end of the BODY $rcmail->output->add_footer($html); } From 315079c8e41c25da93bbfe8b3fe19cc7698b6282 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Mon, 7 Jan 2019 13:04:55 +0000 Subject: [PATCH 07/98] Fix bug where hidden ldap addressbooks would still be visible (Bifrost#T171965) --- plugins/kolab_addressbook/kolab_addressbook.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/kolab_addressbook/kolab_addressbook.php b/plugins/kolab_addressbook/kolab_addressbook.php index 2ddf8db2..37178d0f 100644 --- a/plugins/kolab_addressbook/kolab_addressbook.php +++ b/plugins/kolab_addressbook/kolab_addressbook.php @@ -204,8 +204,9 @@ class kolab_addressbook extends rcube_plugin $jsdata = array(); $sources = (array)$this->rc->get_address_sources(); - // list all non-kolab sources first - foreach (array_filter($sources, function($source){ return empty($source['kolab']); }) as $j => $source) { + // list all non-kolab sources first (also exclude hidden sources) + $filter = function($source){ return empty($source['kolab']) && empty($source['hidden']); }; + foreach (array_filter($sources, $filter) as $j => $source) { $id = strval(strlen($source['id']) ? $source['id'] : $j); $out .= $this->addressbook_list_item($id, $source, $jsdata) . ''; } From 1eaea682cc5d3cf287d6ac5fd2951b1f3dd71f6a Mon Sep 17 00:00:00 2001 From: "Jeroen van Meeuwen (Kolab Systems)" Date: Sat, 19 Jan 2019 08:44:49 +0100 Subject: [PATCH 08/98] Adjust the ActiveSync device setup URL to https://kb.kolabenterprise.com/documentation/setting-up-an-activesync-client --- plugins/kolab_activesync/config.inc.php.dist | 2 +- plugins/kolab_activesync/kolab_activesync_ui.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/kolab_activesync/config.inc.php.dist b/plugins/kolab_activesync/config.inc.php.dist index adcc3787..7cab16ca 100644 --- a/plugins/kolab_activesync/config.inc.php.dist +++ b/plugins/kolab_activesync/config.inc.php.dist @@ -1,4 +1,4 @@ Date: Sat, 19 Jan 2019 09:00:11 +0100 Subject: [PATCH 09/98] Bump versions to 3.4.2 --- plugins/calendar/composer.json | 2 +- plugins/kolab_activesync/composer.json | 2 +- plugins/kolab_addressbook/composer.json | 2 +- plugins/kolab_files/composer.json | 2 +- plugins/kolab_sso/composer.json | 2 +- plugins/kolab_tags/composer.json | 2 +- plugins/libcalendaring/composer.json | 2 +- plugins/libkolab/composer.json | 2 +- plugins/logon_page/composer.json | 2 +- plugins/tasklist/composer.json | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/calendar/composer.json b/plugins/calendar/composer.json index 10335785..4acb53ae 100644 --- a/plugins/calendar/composer.json +++ b/plugins/calendar/composer.json @@ -4,7 +4,7 @@ "description": "Calendar plugin", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.4.1", + "version": "3.4.2", "authors": [ { "name": "Thomas Bruederli", diff --git a/plugins/kolab_activesync/composer.json b/plugins/kolab_activesync/composer.json index ee564408..f906bf45 100644 --- a/plugins/kolab_activesync/composer.json +++ b/plugins/kolab_activesync/composer.json @@ -4,7 +4,7 @@ "description": "ActiveSync configuration utility for Kolab accounts", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.4.0", + "version": "3.4.2", "authors": [ { "name": "Thomas Bruederli", diff --git a/plugins/kolab_addressbook/composer.json b/plugins/kolab_addressbook/composer.json index b533033d..7cf1580c 100644 --- a/plugins/kolab_addressbook/composer.json +++ b/plugins/kolab_addressbook/composer.json @@ -4,7 +4,7 @@ "description": "Kolab addressbook", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.4.1", + "version": "3.4.2", "authors": [ { "name": "Thomas Bruederli", diff --git a/plugins/kolab_files/composer.json b/plugins/kolab_files/composer.json index 9070086c..a03acd87 100644 --- a/plugins/kolab_files/composer.json +++ b/plugins/kolab_files/composer.json @@ -4,7 +4,7 @@ "description": "User interface for Kolab File Manager (Chwala)", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.4.1", + "version": "3.4.2", "authors": [ { "name": "Aleksander Machniak", diff --git a/plugins/kolab_sso/composer.json b/plugins/kolab_sso/composer.json index d3e52052..6133f735 100644 --- a/plugins/kolab_sso/composer.json +++ b/plugins/kolab_sso/composer.json @@ -4,7 +4,7 @@ "description": "Single Sign On for Kolab", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.4.1", + "version": "3.4.2", "authors": [ { "name": "Aleksander Machniak", diff --git a/plugins/kolab_tags/composer.json b/plugins/kolab_tags/composer.json index 80c5218c..6ba1dfa4 100644 --- a/plugins/kolab_tags/composer.json +++ b/plugins/kolab_tags/composer.json @@ -4,7 +4,7 @@ "description": "Email tags plugin", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.4.0", + "version": "3.4.2", "authors": [ { "name": "Aleksander Machniak", diff --git a/plugins/libcalendaring/composer.json b/plugins/libcalendaring/composer.json index ce593a4b..853a133e 100644 --- a/plugins/libcalendaring/composer.json +++ b/plugins/libcalendaring/composer.json @@ -4,7 +4,7 @@ "description": "Library providing common functions for calendaring plugins", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.4.1", + "version": "3.4.2", "authors": [ { "name": "Thomas Bruederli", diff --git a/plugins/libkolab/composer.json b/plugins/libkolab/composer.json index a2efd34f..c2967780 100644 --- a/plugins/libkolab/composer.json +++ b/plugins/libkolab/composer.json @@ -4,7 +4,7 @@ "description": "Plugin to setup a basic environment for the interaction with a Kolab server.", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.4.1", + "version": "3.4.2", "authors": [ { "name": "Thomas Bruederli", diff --git a/plugins/logon_page/composer.json b/plugins/logon_page/composer.json index 974e5eb3..28c56dfc 100644 --- a/plugins/logon_page/composer.json +++ b/plugins/logon_page/composer.json @@ -4,7 +4,7 @@ "description": "Logon screen additions", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.4.0", + "version": "3.4.2", "authors": [ { "name": "Aleksander Machniak", diff --git a/plugins/tasklist/composer.json b/plugins/tasklist/composer.json index f38970de..00d957c5 100644 --- a/plugins/tasklist/composer.json +++ b/plugins/tasklist/composer.json @@ -4,7 +4,7 @@ "description": "Task management plugin", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.4.1", + "version": "3.4.2", "authors": [ { "name": "Thomas Bruederli", From 5834133fadb9eaf798d98e2aabe159748a0bf9db Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Tue, 22 Jan 2019 07:32:42 +0000 Subject: [PATCH 10/98] Unbreak de_DE localization file --- plugins/tasklist/localization/de_DE.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/tasklist/localization/de_DE.inc b/plugins/tasklist/localization/de_DE.inc index 65d7e644..0d930c5d 100644 --- a/plugins/tasklist/localization/de_DE.inc +++ b/plugins/tasklist/localization/de_DE.inc @@ -234,8 +234,8 @@ $labels['importsuccess'] = '$nr Aufgaben erfolgreich importiert'; $labels['importerror'] = 'Fehler beim Importieren'; $labels['newerversionexists'] = 'Eine neuere Version dieser Aufgabe existiert bereits! Abbruch.'; $labels['nowritetasklistfound'] = 'Keine Aufgabenliste zum Speichern der Aufgabe gefunden'; -$labels['importedsuccessfully'] = 'Die Aufgabe wurde erfolgreich unter '$list' gespeichert'; -$labels['updatedsuccessfully'] = 'Die Aufgabe wurde erfolgreich in '$list' aktualisiert'; +$labels['importedsuccessfully'] = 'Die Aufgabe wurde erfolgreich unter \'$list\' gespeichert'; +$labels['updatedsuccessfully'] = 'Die Aufgabe wurde erfolgreich in \'$list\' aktualisiert'; $labels['attendeupdateesuccess'] = 'Teilnehmerstatus erfolgreich aktualisiert'; $labels['itipresponseerror'] = 'Senden der Antwort auf diese Aufgabenzuweisung fehlgeschlagen'; $labels['itipinvalidrequest'] = 'Diese Einladung ist nicht mehr gültig.'; From 4b0562086724d6b4d5f1537a5d42a0a6034e8351 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Tue, 22 Jan 2019 09:44:45 +0000 Subject: [PATCH 11/98] Elastic: Fix Save/Edit buttons on plain text editor (Bifrost#T173153) --- plugins/kolab_files/kolab_files.js | 11 ++++++---- plugins/kolab_files/skins/elastic/ui.js | 27 ++++++++++++------------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/plugins/kolab_files/kolab_files.js b/plugins/kolab_files/kolab_files.js index 3a60ddb1..c32ea009 100644 --- a/plugins/kolab_files/kolab_files.js +++ b/plugins/kolab_files/kolab_files.js @@ -1251,10 +1251,6 @@ function kolab_files_frame_load(frame) } catch (e) {}; - // on edit page switch immediately to edit mode - if (rcmail.file_editor && rcmail.file_editor.editable && rcmail.env.action == 'edit') - rcmail.files_edit(); - rcmail.enable_command('files-edit', (rcmail.file_editor && rcmail.file_editor.editable) || rcmail.env.editor_type || (file_api.file_type_supported(rcmail.env.file_data.type, rcmail.env.files_caps) & 4)); @@ -1266,6 +1262,10 @@ function kolab_files_frame_load(frame) rcmail.enable_command('image-scale', 'image-rotate', info && !!/^image\//.test(info.type)); rcmail.gui_objects.messagepartframe = frame; + // on edit page switch immediately to edit mode + if (rcmail.file_editor && rcmail.file_editor.editable && rcmail.env.action == 'edit') + rcmail.files_edit(); + // detect Print button and check if it can be accessed try { if ($('#fileframe').contents().find('#print').length) @@ -3895,6 +3895,9 @@ function kolab_files_ui() _frame: 1 }; + if (rcmail.is_framed()) + args._framed = 1; + if (params && params.session) args._session = params.session; diff --git a/plugins/kolab_files/skins/elastic/ui.js b/plugins/kolab_files/skins/elastic/ui.js index 48c23dfa..33edbb12 100644 --- a/plugins/kolab_files/skins/elastic/ui.js +++ b/plugins/kolab_files/skins/elastic/ui.js @@ -78,9 +78,20 @@ function kolab_files_members_list(link) }; -if (rcmail.env.action == 'open') { +if (rcmail.env.action == 'open' || rcmail.env.action == 'edit') { rcmail.addEventListener('enable-command', kolab_files_enable_command); + if (rcmail.env.action == 'open') { + $('#toolbar-menu a.button.save').parent().hide(); + } + else if (rcmail.env.action == 'edit') { + if (rcmail.env.editor_type == 'wopi' && rcmail.is_framed()) { + parent.$('.ui-dialog:visible .ui-dialog-buttonpane').addClass('hidden'); + } + + rcmail.gui_object('exportmenu', 'export-menu'); + } + // center and scale the image in preview frame if (rcmail.env.mimetype.startsWith('image/')) { $('#fileframe').on('load', function() { @@ -92,7 +103,7 @@ if (rcmail.env.action == 'open') { } // Elastic mobile preview uses an iframe in a dialog - if (rcmail.is_framed()) { + if ((rcmail.env.action == 'open' || rcmail.env.editor_type != 'wopi') && rcmail.is_framed()) { var edit_button = $('#filetoolbar a.button.edit'), save_button = $('#filetoolbar a.button.save'); @@ -111,9 +122,6 @@ if (rcmail.env.action == 'open') { ); } } -else if (rcmail.env.action == 'edit') { - rcmail.gui_object('exportmenu', 'export-menu'); -} else { rcmail.addEventListener('files-folder-select', function(p) { var is_sess = p.folder == 'folder-collection-sessions'; @@ -126,15 +134,6 @@ else { } $(document).ready(function() { - if (rcmail.env.action == 'open') { - $('#toolbar-menu a.button.save').parent().hide(); - } - else if (rcmail.env.action == 'edit') { - if (rcmail.is_framed()) { - parent.$('.ui-dialog:visible .ui-dialog-buttonpane').addClass('hidden'); - } - } - if ($('#dragfilemenu').length) { rcmail.gui_object('file_dragmenu', 'dragfilemenu'); } From c1f1c9daed24b044819a66e38da6e7b39311f801 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Wed, 23 Jan 2019 08:17:36 +0100 Subject: [PATCH 12/98] Use https:// for plugins.roundcube.net --- plugins/calendar/composer.json | 2 +- plugins/html_converter/composer.json | 2 +- plugins/kolab_2fa/composer.json | 2 +- plugins/kolab_activesync/composer.json | 2 +- plugins/kolab_addressbook/composer.json | 2 +- plugins/kolab_auth/composer.json | 2 +- plugins/kolab_chat/composer.json | 2 +- plugins/kolab_config/composer.json | 2 +- plugins/kolab_delegation/composer.json | 2 +- plugins/kolab_files/composer.json | 2 +- plugins/kolab_folders/composer.json | 2 +- plugins/kolab_notes/composer.json | 2 +- plugins/kolab_shortcuts/composer.json | 2 +- plugins/kolab_sso/composer.json | 2 +- plugins/kolab_tags/composer.json | 2 +- plugins/ldap_authentication/composer.json | 2 +- plugins/libcalendaring/composer.json | 2 +- plugins/libkolab/composer.json | 2 +- plugins/logon_page/composer.json | 2 +- plugins/odfviewer/composer.json | 2 +- plugins/pdfviewer/composer.json | 2 +- plugins/tasklist/composer.json | 2 +- plugins/tinymce_config/composer.json | 2 +- plugins/wap_client/composer.json | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/plugins/calendar/composer.json b/plugins/calendar/composer.json index 4acb53ae..21a9d0e6 100644 --- a/plugins/calendar/composer.json +++ b/plugins/calendar/composer.json @@ -20,7 +20,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/html_converter/composer.json b/plugins/html_converter/composer.json index ea8e8ccc..aad79630 100644 --- a/plugins/html_converter/composer.json +++ b/plugins/html_converter/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/kolab_2fa/composer.json b/plugins/kolab_2fa/composer.json index e7ee99fe..a3525d95 100644 --- a/plugins/kolab_2fa/composer.json +++ b/plugins/kolab_2fa/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/kolab_activesync/composer.json b/plugins/kolab_activesync/composer.json index f906bf45..125cb443 100644 --- a/plugins/kolab_activesync/composer.json +++ b/plugins/kolab_activesync/composer.json @@ -20,7 +20,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/kolab_addressbook/composer.json b/plugins/kolab_addressbook/composer.json index 7cf1580c..5de24973 100644 --- a/plugins/kolab_addressbook/composer.json +++ b/plugins/kolab_addressbook/composer.json @@ -20,7 +20,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/kolab_auth/composer.json b/plugins/kolab_auth/composer.json index 94655668..c34a9c8b 100644 --- a/plugins/kolab_auth/composer.json +++ b/plugins/kolab_auth/composer.json @@ -20,7 +20,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/kolab_chat/composer.json b/plugins/kolab_chat/composer.json index 8db1e282..4f79a302 100644 --- a/plugins/kolab_chat/composer.json +++ b/plugins/kolab_chat/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/kolab_config/composer.json b/plugins/kolab_config/composer.json index a766117b..89ec7177 100644 --- a/plugins/kolab_config/composer.json +++ b/plugins/kolab_config/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/kolab_delegation/composer.json b/plugins/kolab_delegation/composer.json index f69a9a74..0cfb12c2 100644 --- a/plugins/kolab_delegation/composer.json +++ b/plugins/kolab_delegation/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/kolab_files/composer.json b/plugins/kolab_files/composer.json index a03acd87..7fa6e690 100644 --- a/plugins/kolab_files/composer.json +++ b/plugins/kolab_files/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/kolab_folders/composer.json b/plugins/kolab_folders/composer.json index 86ccace3..822c7cec 100644 --- a/plugins/kolab_folders/composer.json +++ b/plugins/kolab_folders/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/kolab_notes/composer.json b/plugins/kolab_notes/composer.json index d2ecf3fa..5ee7247f 100644 --- a/plugins/kolab_notes/composer.json +++ b/plugins/kolab_notes/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/kolab_shortcuts/composer.json b/plugins/kolab_shortcuts/composer.json index 1a2bc58b..f24db87b 100644 --- a/plugins/kolab_shortcuts/composer.json +++ b/plugins/kolab_shortcuts/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/kolab_sso/composer.json b/plugins/kolab_sso/composer.json index 6133f735..72554a47 100644 --- a/plugins/kolab_sso/composer.json +++ b/plugins/kolab_sso/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/kolab_tags/composer.json b/plugins/kolab_tags/composer.json index 6ba1dfa4..d74d6906 100644 --- a/plugins/kolab_tags/composer.json +++ b/plugins/kolab_tags/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/ldap_authentication/composer.json b/plugins/ldap_authentication/composer.json index 4076d1cc..129d2598 100644 --- a/plugins/ldap_authentication/composer.json +++ b/plugins/ldap_authentication/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/libcalendaring/composer.json b/plugins/libcalendaring/composer.json index 853a133e..54ec3ea8 100644 --- a/plugins/libcalendaring/composer.json +++ b/plugins/libcalendaring/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/libkolab/composer.json b/plugins/libkolab/composer.json index c2967780..1fccbb80 100644 --- a/plugins/libkolab/composer.json +++ b/plugins/libkolab/composer.json @@ -20,7 +20,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/logon_page/composer.json b/plugins/logon_page/composer.json index 28c56dfc..66e77b70 100644 --- a/plugins/logon_page/composer.json +++ b/plugins/logon_page/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/odfviewer/composer.json b/plugins/odfviewer/composer.json index 732c61af..7894c0b4 100644 --- a/plugins/odfviewer/composer.json +++ b/plugins/odfviewer/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/pdfviewer/composer.json b/plugins/pdfviewer/composer.json index 98121c09..e021c924 100644 --- a/plugins/pdfviewer/composer.json +++ b/plugins/pdfviewer/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/tasklist/composer.json b/plugins/tasklist/composer.json index 00d957c5..7cd3280a 100644 --- a/plugins/tasklist/composer.json +++ b/plugins/tasklist/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/tinymce_config/composer.json b/plugins/tinymce_config/composer.json index 41a7b367..9ff2a4aa 100644 --- a/plugins/tinymce_config/composer.json +++ b/plugins/tinymce_config/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { diff --git a/plugins/wap_client/composer.json b/plugins/wap_client/composer.json index 3d4a0453..ebcbc12a 100644 --- a/plugins/wap_client/composer.json +++ b/plugins/wap_client/composer.json @@ -15,7 +15,7 @@ "repositories": [ { "type": "composer", - "url": "http://plugins.roundcube.net" + "url": "https://plugins.roundcube.net" } ], "require": { From cbd1c1ae47b91a70ad1dfeab31d54aa95b13f2d4 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Wed, 30 Jan 2019 15:30:11 +0100 Subject: [PATCH 13/98] Upgrade to fullCalendar 3.9.0 Squashed commit of the following: commit cd7c726b57edaa7997e0ebed27b5b5ec8ae7fb1e Author: Aleksander Machniak Date: Tue Jan 22 13:52:35 2019 +0000 Remove leftover code Agenda sections and fisheye view. commit 8b2203adfc03746872183e2d211ad1fe1798730e Author: Aleksander Machniak Date: Tue Jan 22 12:23:11 2019 +0000 Fix duplicated requests on using Next/Prev buttons in Agenda view commit 2dff07962566c13ef38703cc23d4f6b234b80303 Author: Aleksander Machniak Date: Tue Jan 22 11:34:16 2019 +0000 Increase font-size for .fc-event commit 9bb48ec3fa1d3a4eb255870b1a91ace55dbc5b95 Author: Aleksander Machniak Date: Fri Jan 18 12:10:33 2019 +0000 Fix re-fetching updated event in quickview mode commit 841815f5b1a5581f607bd5ee05e15e9c8476f4bc Merge: ffe9c0c7 315079c8 Author: Aleksander Machniak Date: Fri Jan 18 11:43:19 2019 +0000 Merge branch 'master' into dev/fullcalendar-upgrade commit ffe9c0c7f7efd217e01cdcaed23e135058ef65b2 Author: Aleksander Machniak Date: Fri Jan 18 11:41:59 2019 +0000 Fix events re-rendering after "Print descriptions" option change commit bc48cd6639fd50f7e5236945ec9661c11d614595 Author: Aleksander Machniak Date: Fri Jan 18 11:30:38 2019 +0000 Fix event color on hover in print mode commit 0776636fd60258f05aa5f1877c365e040bc1fa7b Author: Aleksander Machniak Date: Fri Jan 18 10:07:41 2019 +0000 Fix including eye.svg commit 7cc525e4e92407069e22a59c9976ded24cabe940 Author: Aleksander Machniak Date: Fri Jan 18 09:50:34 2019 +0000 Elastic support for new fullCalendar commit 3efc8d038986859a388dd7653ab00a1f0ee82914 Author: Aleksander Machniak Date: Thu Jan 17 07:47:59 2019 +0000 Remove now indicator on calendar print commit a1d018875bc0065f372b6483ff3b1be13f4c787c Author: Aleksander Machniak Date: Wed Jan 16 13:40:11 2019 +0100 Calendar agenda view and printing Note that agenda's smart sections feature is not implemented (yet) as it does not exist in fullCalendar (it was a Kolab's customization). commit ea873a9589a11a33ee49f27abf9ac30af9a1690b Author: Aleksander Machniak Date: Tue Jan 15 12:18:21 2019 +0100 Calendar Agenda and searching fixes commit fb0c3436a34e4507ee454d16cc257be33659e3da Author: Aleksander Machniak Date: Fri Jan 11 13:59:29 2019 +0100 Varius calendar fixes and cleanups commit d45f3439b9e41fe4d25e647949b37255ebfc5068 Author: Aleksander Machniak Date: Wed Jan 9 13:22:24 2019 +0100 Fix various Larry skin regressions after fullCalendar upgrade commit 3373fff6b3f73a05811efead66c7b5747adb2ba7 Author: Aleksander Machniak Date: Wed Jan 9 10:51:16 2019 +0100 Fix .fc-today style commit 5718fd40e34d93b1c57f529bb53544ce156a1913 Author: Aleksander Machniak Date: Wed Jan 9 10:31:22 2019 +0100 Fix various date calculation issues after fullCalendar upgrade - allDay flag must be boolean - allDay event's end date must be exclusive commit d08e8a8a3b4f97781cd1980b714886507d129cf5 Author: Aleksander Machniak Date: Tue Jan 8 11:39:10 2019 +0100 Fix date/time format issies and inconsistencies, remove confusing config commit b0196c7ff1d71149fec5fd619220faf9f5f6a612 Author: Aleksander Machniak Date: Mon Jan 7 15:46:51 2019 +0000 Fox some small issues after fullCalendar update commit c7b561f19daacdd72853a300e22fdc025bf3db28 Author: Aleksander Machniak Date: Mon Jan 7 13:22:57 2019 +0000 Fix handling 'source' argument in load_events request commit 59fc3c816887a2aa591e4c4237e2f4fff131bbb0 Author: Aleksander Machniak Date: Mon Jan 7 12:26:04 2019 +0000 Fix including moment.js commit eb85d762c75cf11fcbe1f40010bef7d4794be23a Author: Aleksander Machniak Date: Fri Jan 4 16:12:33 2019 +0000 Upgrade to fullcalendar 3.9.0 - Part I Just started, still many issues, no printing, no elastic, no agenda view --- plugins/calendar/calendar.php | 87 +- plugins/calendar/calendar_ui.js | 674 +- plugins/calendar/config.inc.php.dist | 27 - plugins/calendar/lib/calendar_ui.php | 42 +- plugins/calendar/lib/js/fullcalendar.js | 21851 +++++++++++----- plugins/calendar/lib/js/moment.js | 4511 ++++ plugins/calendar/print.js | 173 +- plugins/calendar/skins/larry/calendar.css | 294 +- plugins/calendar/skins/larry/fullcalendar.css | 1846 +- plugins/calendar/skins/larry/print.css | 117 +- plugins/libcalendaring/libcalendaring.js | 69 +- plugins/libcalendaring/libcalendaring.php | 52 +- plugins/libkolab/skins/elastic/images/eye.svg | 2 +- .../skins/elastic/include/calendar.less | 1223 +- .../skins/elastic/include/fullcalendar.less | 1246 + .../skins/elastic/include/libcalendaring.less | 4 +- plugins/tasklist/tasklist.js | 25 +- 17 files changed, 22949 insertions(+), 9294 deletions(-) create mode 100644 plugins/calendar/lib/js/moment.js create mode 100644 plugins/libkolab/skins/elastic/include/fullcalendar.less diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index 0ef2e8c0..afb23854 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -50,7 +50,6 @@ class calendar extends rcube_plugin 'calendar_work_start' => 6, 'calendar_work_end' => 18, 'calendar_agenda_range' => 60, - 'calendar_agenda_sections' => 'smart', 'calendar_event_coloring' => 0, 'calendar_time_indicator' => true, 'calendar_allow_invite_shared' => false, @@ -296,7 +295,6 @@ class calendar extends rcube_plugin return $calendar ?: $first; } - /** * Render the main calendar view from skin template */ @@ -304,9 +302,6 @@ class calendar extends rcube_plugin { $this->rc->output->set_pagetitle($this->gettext('calendar')); - // Add CSS stylesheets to the page header - $this->ui->addCSS(); - // Add JS files to the page header $this->ui->addJS(); @@ -326,7 +321,7 @@ class calendar extends rcube_plugin ))); $view = rcube_utils::get_input_value('view', rcube_utils::INPUT_GPC); - if (in_array($view, array('agendaWeek', 'agendaDay', 'month', 'table'))) + if (in_array($view, array('agendaWeek', 'agendaDay', 'month', 'list'))) $this->rc->output->set_env('view', $view); if ($date = rcube_utils::get_input_value('date', rcube_utils::INPUT_GPC)) @@ -378,14 +373,15 @@ class calendar extends rcube_plugin } $field_id = 'rcmfd_default_view'; + $view = $this->rc->config->get('calendar_default_view', $this->defaults['calendar_default_view']); $select = new html_select(array('name' => '_default_view', 'id' => $field_id)); $select->add($this->gettext('day'), "agendaDay"); $select->add($this->gettext('week'), "agendaWeek"); $select->add($this->gettext('month'), "month"); - $select->add($this->gettext('agenda'), "table"); + $select->add($this->gettext('agenda'), "list"); $p['blocks']['view']['options']['default_view'] = array( 'title' => html::label($field_id, rcube::Q($this->gettext('default_view'))), - 'content' => $select->show($this->rc->config->get('calendar_default_view', $this->defaults['calendar_default_view'])), + 'content' => $select->show($view == 'table' ? 'list' : $view), ); } @@ -1323,12 +1319,21 @@ class calendar extends rcube_plugin */ function load_events() { - $events = $this->driver->load_events( - rcube_utils::get_input_value('start', rcube_utils::INPUT_GET), - rcube_utils::get_input_value('end', rcube_utils::INPUT_GET), - ($query = rcube_utils::get_input_value('q', rcube_utils::INPUT_GET)), - rcube_utils::get_input_value('source', rcube_utils::INPUT_GET) - ); + $start = rcube_utils::get_input_value('start', rcube_utils::INPUT_GET); + $end = rcube_utils::get_input_value('end', rcube_utils::INPUT_GET); + $query = rcube_utils::get_input_value('q', rcube_utils::INPUT_GET); + $source = rcube_utils::get_input_value('source', rcube_utils::INPUT_GET); + + if (!is_numeric($start) || strpos($start, 'T')) { + $start = new DateTime($start, $this->timezone); + $start = $start->getTimestamp(); + } + if (!is_numeric($end) || strpos($end, 'T')) { + $end = new DateTime($end, $this->timezone); + $end = $end->getTimestamp(); + } + + $events = $this->driver->load_events($start, $end, $query, $source); echo $this->encode($events, !empty($query)); exit; } @@ -1767,15 +1772,12 @@ class calendar extends rcube_plugin // configuration $settings['default_calendar'] = $this->rc->config->get('calendar_default_calendar'); $settings['default_view'] = (string)$this->rc->config->get('calendar_default_view', $this->defaults['calendar_default_view']); - $settings['date_agenda'] = (string)$this->rc->config->get('calendar_date_agenda', $this->defaults['calendar_date_agenda']); - $settings['timeslots'] = (int)$this->rc->config->get('calendar_timeslots', $this->defaults['calendar_timeslots']); $settings['first_day'] = (int)$this->rc->config->get('calendar_first_day', $this->defaults['calendar_first_day']); $settings['first_hour'] = (int)$this->rc->config->get('calendar_first_hour', $this->defaults['calendar_first_hour']); $settings['work_start'] = (int)$this->rc->config->get('calendar_work_start', $this->defaults['calendar_work_start']); $settings['work_end'] = (int)$this->rc->config->get('calendar_work_end', $this->defaults['calendar_work_end']); $settings['agenda_range'] = (int)$this->rc->config->get('calendar_agenda_range', $this->defaults['calendar_agenda_range']); - $settings['agenda_sections'] = $this->rc->config->get('calendar_agenda_sections', $this->defaults['calendar_agenda_sections']); $settings['event_coloring'] = (int)$this->rc->config->get('calendar_event_coloring', $this->defaults['calendar_event_coloring']); $settings['time_indicator'] = (int)$this->rc->config->get('calendar_time_indicator', $this->defaults['calendar_time_indicator']); $settings['invite_shared'] = (int)$this->rc->config->get('calendar_allow_invite_shared', $this->defaults['calendar_allow_invite_shared']); @@ -1889,24 +1891,35 @@ class calendar extends rcube_plugin $event['description'] = trim($h2t->get_text()); } - // mapping url => vurl because of the fullcalendar client script + // mapping url => vurl, allday => allDay because of the fullcalendar client script $event['vurl'] = $event['url']; + $event['allDay'] = !empty($event['allday']); unset($event['url']); + unset($event['allday']); + + $event['className'] = $event['className'] ? explode(' ', $event['className']) : array(); + if ($addcss) { + $event['className'][] = 'fc-event-cal-' . asciiwords($event['calendar'], true); + } + + if ($event['allDay']) { + $event['end'] = $event['end']->add(new DateInterval('P1D')); + } + + if ($_GET['mode'] == 'print') { + $event['editable'] = false; + } return array( '_id' => $event['calendar'] . ':' . $event['id'], // unique identifier for fullcalendar - 'start' => $this->lib->adjust_timezone($event['start'], $event['allday'])->format('c'), - 'end' => $this->lib->adjust_timezone($event['end'], $event['allday'])->format('c'), + 'start' => $this->lib->adjust_timezone($event['start'], $event['allDay'])->format('c'), + 'end' => $this->lib->adjust_timezone($event['end'], $event['allDay'])->format('c'), // 'changed' might be empty for event recurrences (Bug #2185) 'changed' => $event['changed'] ? $this->lib->adjust_timezone($event['changed'])->format('c') : null, 'created' => $event['created'] ? $this->lib->adjust_timezone($event['created'])->format('c') : null, 'title' => strval($event['title']), 'description' => strval($event['description']), 'location' => strval($event['location']), - 'className' => ($addcss ? 'fc-event-cal-'.asciiwords($event['calendar'], true).' ' : '') . - 'fc-event-cat-' . asciiwords(strtolower(join('-', (array)$event['categories'])), true) . - rtrim(' ' . $event['className']), - 'allDay' => ($event['allday'] == 1), ) + $event; } @@ -2056,7 +2069,8 @@ class calendar extends rcube_plugin // convert dates into DateTime objects in user's current timezone $event['start'] = new DateTime($event['start'], $this->timezone); $event['end'] = new DateTime($event['end'], $this->timezone); - $event['allday'] = (bool)$event['allday']; + $event['allday'] = !empty($event['allDay']); + unset($event['allDay']); // start/end is all we need for 'move' action (#1480) if ($action == 'move') { @@ -2410,10 +2424,10 @@ class calendar extends rcube_plugin $title = $this->gettext('print'); $view = rcube_utils::get_input_value('view', rcube_utils::INPUT_GPC); - if (!in_array($view, array('agendaWeek', 'agendaDay', 'month', 'table'))) + if (!in_array($view, array('agendaWeek', 'agendaDay', 'month', 'list'))) $view = 'agendaDay'; - $this->rc->output->set_env('view',$view); + $this->rc->output->set_env('view', $view); if ($date = rcube_utils::get_input_value('date', rcube_utils::INPUT_GPC)) $this->rc->output->set_env('date', $date); @@ -2421,28 +2435,19 @@ class calendar extends rcube_plugin if ($range = rcube_utils::get_input_value('range', rcube_utils::INPUT_GPC)) $this->rc->output->set_env('listRange', intval($range)); - if (isset($_REQUEST['sections'])) - $this->rc->output->set_env('listSections', rcube_utils::get_input_value('sections', rcube_utils::INPUT_GPC)); - if ($search = rcube_utils::get_input_value('search', rcube_utils::INPUT_GPC)) { $this->rc->output->set_env('search', $search); $title .= ' "' . $search . '"'; } - // Add CSS stylesheets to the page header - $skin_path = $this->local_skin_path(); - $this->include_stylesheet($skin_path . '/fullcalendar.css'); - $this->include_stylesheet($skin_path . '/print.css'); - - // Add JS files to the page header - $this->include_script('print.js'); - $this->include_script('lib/js/fullcalendar.js'); - + // Add JS to the page + $this->ui->addJS(); + $this->register_handler('plugin.calendar_css', array($this->ui, 'calendar_css')); $this->register_handler('plugin.calendar_list', array($this->ui, 'calendar_list')); - + $this->rc->output->set_pagetitle($title); - $this->rc->output->send("calendar.print"); + $this->rc->output->send('calendar.print'); } /** diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js index 99f9c09f..1253e0d6 100644 --- a/plugins/calendar/calendar_ui.js +++ b/plugins/calendar/calendar_ui.js @@ -71,96 +71,92 @@ function rcube_calendar_ui(settings) var sensitivitylabels = { 'public':rcmail.gettext('public','calendar'), 'private':rcmail.gettext('private','calendar'), 'confidential':rcmail.gettext('confidential','calendar') }; var ui_loading = rcmail.set_busy(true, 'loading'); - // general datepicker settings - var datepicker_settings = { - // translate from fullcalendar format to datepicker format - dateFormat: settings.date_format.replace(/M/g, 'm').replace(/mmmmm/, 'MM').replace(/mmm/, 'M').replace(/dddd/, 'DD').replace(/ddd/, 'D').replace(/yy/g, 'y'), - firstDay: settings.first_day, - // dayNamesMin: settings.days_short, - monthNames: settings.months, - monthNamesShort: settings.months, - changeMonth: false, - showWeek: settings.show_weekno >= 0, - showOtherMonths: true, - selectOtherMonths: true - }; - // global fullcalendar settings var fullcalendar_defaults = { + theme: false, aspectRatio: 1, - ignoreTimezone: true, // will treat the given date strings as in local (browser's) timezone - monthNames : settings.months, - monthNamesShort : settings.months_short, - dayNames : settings.days, - dayNamesShort : settings.days_short, - firstDay : settings.first_day, - firstHour : settings.first_hour, - slotMinutes : 60/settings.timeslots, - timeFormat: { - '': settings.time_format, - agenda: settings.time_format + '{ - ' + settings.time_format + '}', - list: settings.time_format + '{ - ' + settings.time_format + '}', - table: settings.time_format + '{ - ' + settings.time_format + '}' - }, - axisFormat : settings.time_format, - columnFormat: { - month: 'ddd', // Mon - week: 'ddd ' + settings.date_short, // Mon 9/7 - day: 'dddd ' + settings.date_short, // Monday 9/7 - table: settings.date_agenda - }, - titleFormat: { - month: 'MMMM yyyy', - week: settings.dates_long, - day: 'dddd ' + settings.date_long, - table: settings.dates_long - }, - listPage: 7, // advance one week in agenda view - listRange: settings.agenda_range, - listSections: settings.agenda_sections, - tableCols: ['handle', 'date', 'time', 'title', 'location'], - defaultView: rcmail.env.view || settings.default_view, - allDayText: rcmail.gettext('all-day', 'calendar'), + timezone: false, // will treat the given date strings as in local (browser's) timezone + monthNames: settings.months, + monthNamesShort: settings.months_short, + dayNames: settings.days, + dayNamesShort: settings.days_short, weekNumbers: settings.show_weekno > 0, weekNumberTitle: rcmail.gettext('weekshort', 'calendar') + ' ', + firstDay: settings.first_day, + firstHour: settings.first_hour, + slotDuration: {minutes: 60/settings.timeslots}, + businessHours: { + start: settings.work_start + ':00', + end: settings.work_end + ':00' + }, + scrollTime: settings.work_start + ':00', + views: { + list: { + titleFormat: settings.dates_long, + listDayFormat: settings.date_long, + visibleRange: function(currentDate) { + return { + start: currentDate.clone(), + end: currentDate.clone().add(settings.agenda_range, 'days') + } + } + }, + month: { + columnFormat: 'ddd', // Mon + titleFormat: 'MMMM YYYY', + eventLimit: 4 + }, + week: { + columnFormat: 'ddd ' + settings.date_short, // Mon 9/7 + titleFormat: settings.dates_long + }, + day: { + columnFormat: 'dddd ' + settings.date_short, // Monday 9/7 + titleFormat: 'dddd ' + settings.date_long + } + }, + timeFormat: settings.time_format, + slotLabelFormat: settings.time_format, + defaultView: rcmail.env.view || settings.default_view, + allDayText: rcmail.gettext('all-day', 'calendar'), buttonText: { - prev: ' ◄ ', - next: ' ► ', today: settings['today'], day: rcmail.gettext('day', 'calendar'), week: rcmail.gettext('week', 'calendar'), month: rcmail.gettext('month', 'calendar'), - table: rcmail.gettext('agenda', 'calendar') + list: rcmail.gettext('agenda', 'calendar') }, - listTexts: { - until: rcmail.gettext('until', 'calendar'), - past: rcmail.gettext('pastevents', 'calendar'), - today: rcmail.gettext('today', 'calendar'), - tomorrow: rcmail.gettext('tomorrow', 'calendar'), - thisWeek: rcmail.gettext('thisweek', 'calendar'), - nextWeek: rcmail.gettext('nextweek', 'calendar'), - thisMonth: rcmail.gettext('thismonth', 'calendar'), - nextMonth: rcmail.gettext('nextmonth', 'calendar'), - future: rcmail.gettext('futureevents', 'calendar'), - week: rcmail.gettext('weekofyear', 'calendar') + buttonIcons: { + prev: 'left-single-arrow', + next: 'right-single-arrow' + }, + nowIndicator: settings.time_indicator, + eventLimitText: function(num) { + return rcmail.gettext('andnmore', 'calendar').replace('$nr', num); }, - currentTimeIndicator: settings.time_indicator, // event rendering eventRender: function(event, element, view) { - if (view.name != 'list' && view.name != 'table') { + if (view.name != 'list') { var prefix = event.sensitivity && event.sensitivity != 'public' ? String(sensitivitylabels[event.sensitivity]).toUpperCase()+': ' : ''; element.attr('title', prefix + event.title); } if (view.name != 'month') { - if (event.location) { - element.find('div.fc-event-title').after('
@ ' + Q(event.location) + '
'); + if (view.name == 'list') { + var loc = $('').attr('class', 'fc-event-location'); + if (event.location) + loc.text(event.location); + element.find('.fc-list-item-title').after(loc); } + else if (event.location) { + element.find('div.fc-title').after($('
').html('@ ' + Q(event.location))); + } + var time_element = element.find('div.fc-time'); if (event.sensitivity && event.sensitivity != 'public') - element.find('div.fc-event-time').append(''); + time_element.append(''); if (event.recurrence) - element.find('div.fc-event-time').append(''); + time_element.append(''); if (event.alarms || (event.valarms && event.valarms.length)) - element.find('div.fc-event-time').append(''); + time_element.append(''); } if (event.status) { element.addClass('cal-event-status-' + String(event.status).toLowerCase()); @@ -168,14 +164,9 @@ function rcube_calendar_ui(settings) element.attr('aria-label', event.title + ', ' + me.event_date_text(event, true)); }, - // render element indicating more (invisible) events - overflowRender: function(data, element) { - element.html(rcmail.gettext('andnmore', 'calendar').replace('$nr', data.count)) - .click(function(e){ me.fisheye_view(data.date); }); - }, // callback when a specific event is clicked eventClick: function(event, ev, view) { - if (!event.temp && String(event.className).indexOf('fc-type-freebusy') < 0) + if (!event.temp && (!event.className || event.className.indexOf('fc-type-freebusy') < 0)) event_show_dialog(event, ev); } }; @@ -184,7 +175,6 @@ function rcube_calendar_ui(settings) var Q = this.quote_html; var text2html = this.text2html; var event_date_text = this.event_date_text; - var parse_datetime = this.parse_datetime; var date2unixtime = this.date2unixtime; var fromunixtime = this.fromunixtime; var parseISO8601 = this.parseISO8601; @@ -226,8 +216,8 @@ function rcube_calendar_ui(settings) // clone the given date object and optionally adjust time var clone_date = function(date, adjust) { - var d = new Date(date.getTime()); - + var d = 'toDate' in date ? date.toDate() : new Date(date.getTime()); + // set time to 00:00 if (adjust == 1) { d.setHours(0); @@ -238,7 +228,7 @@ function rcube_calendar_ui(settings) d.setHours(23); d.setMinutes(59); } - + return d; }; @@ -256,6 +246,11 @@ function rcube_calendar_ui(settings) return date2servertime(date).replace(/[^0-9]/g, '').substr(0, (dateonly ? 8 : 14)); } + var format_date = function(date, format) + { + return $.fullCalendar.formatDate('toDate' in date ? date : moment(date), format); + }; + var format_datetime = function(date, mode, voice) { return me.format_datetime(date, mode, voice); @@ -633,11 +628,19 @@ function rcube_calendar_ui(settings) var priority = $('#edit-priority').val(event.priority); var sensitivity = $('#edit-sensitivity').val(event.sensitivity); var syncstart = $('#edit-recurrence-syncstart input'); - var duration = Math.round((event.end.getTime() - event.start.getTime()) / 1000); - var startdate = $('#edit-startdate').val($.fullCalendar.formatDate(event.start, settings['date_format'])).data('duration', duration); - var starttime = $('#edit-starttime').val($.fullCalendar.formatDate(event.start, settings['time_format'])).show(); - var enddate = $('#edit-enddate').val($.fullCalendar.formatDate(event.end, settings['date_format'])); - var endtime = $('#edit-endtime').val($.fullCalendar.formatDate(event.end, settings['time_format'])).show(); + var end = 'toDate' in event.end ? event.end : moment(event.end); + var start = 'toDate' in event.start ? event.start : moment(event.start); + var duration = Math.round((end.format('x') - start.format('x')) / 1000); + + // Correct the fullCalendar end date for all-day events + if (!end.hasTime()) { + end.subtract(1, 'days'); + } + + var startdate = $('#edit-startdate').val(format_date(start, settings.date_format)).data('duration', duration); + var starttime = $('#edit-starttime').val(format_date(start, settings.time_format)).show(); + var enddate = $('#edit-enddate').val(format_date(end, settings.date_format)); + var endtime = $('#edit-endtime').val(format_date(end, settings.time_format)).show(); var allday = $('#edit-allday').get(0); var notify = $('#edit-attendees-donotify').get(0); var invite = $('#edit-attendees-invite').get(0); @@ -765,12 +768,12 @@ function rcube_calendar_ui(settings) // fetch attachments, some drivers doesn't set 'attachments' array for event? } }; - + // init dialog buttons var buttons = [], save_func = function() { - var start = parse_datetime(allday.checked ? '12:00' : starttime.val(), startdate.val()); - var end = parse_datetime(allday.checked ? '13:00' : endtime.val(), enddate.val()); + var start = me.parse_datetime(allday.checked ? '12:00' : starttime.val(), startdate.val()); + var end = me.parse_datetime(allday.checked ? '13:00' : endtime.val(), enddate.val()); // basic input validatetion if (start.getTime() > end.getTime()) { @@ -783,7 +786,7 @@ function rcube_calendar_ui(settings) calendar: event.calendar, start: date2servertime(start), end: date2servertime(end), - allday: allday.checked?1:0, + allDay: allday.checked?1:0, title: title.val(), description: description.val(), location: location.val(), @@ -1146,11 +1149,14 @@ function rcube_calendar_ui(settings) // set form elements var allday = $('#edit-allday').get(0); - var duration = Math.round((event.end.getTime() - event.start.getTime()) / 1000); - freebusy_ui.startdate = $('#schedule-startdate').val($.fullCalendar.formatDate(event.start, settings['date_format'])).data('duration', duration); - freebusy_ui.starttime = $('#schedule-starttime').val($.fullCalendar.formatDate(event.start, settings['time_format'])).show(); - freebusy_ui.enddate = $('#schedule-enddate').val($.fullCalendar.formatDate(event.end, settings['date_format'])); - freebusy_ui.endtime = $('#schedule-endtime').val($.fullCalendar.formatDate(event.end, settings['time_format'])).show(); + var end = 'toDate' in event.end ? event.end : moment(event.end); + var start = 'toDate' in event.start ? event.start : moment(event.start); + var duration = Math.round((end.format('x') - start.format('x')) / 1000); + + freebusy_ui.startdate = $('#schedule-startdate').val(format_date(start, settings.date_format)).data('duration', duration); + freebusy_ui.starttime = $('#schedule-starttime').val(format_date(start, settings.time_format)).show(); + freebusy_ui.enddate = $('#schedule-enddate').val(format_date(end, settings.date_format)); + freebusy_ui.endtime = $('#schedule-endtime').val(format_date(end, settings.time_format)).show(); if (allday.checked) { freebusy_ui.starttime.val("12:00").hide(); @@ -1319,16 +1325,16 @@ function rcube_calendar_ui(settings) for (var s = 0, t = freebusy_ui.start.getTime(); t < freebusy_ui.end.getTime(); s++) { curdate.setTime(t); - datestr = fc.fullCalendar('formatDate', curdate, date_format); + datestr = format_date(curdate, date_format); if (datestr != lastdate) { if (lastdate && !allday) break; - dates_row += '' + Q(datestr) + ''; + dates_row += '' + Q(datestr) + ''; lastdate = datestr; } // set css class according to working hours css = is_weekend(curdate) || (freebusy_ui.interval <= 60 && !is_workinghour(curdate)) ? 'offhours' : 'workinghours'; - times_row += '' + Q(allday ? rcmail.gettext('all-day','calendar') : $.fullCalendar.formatDate(curdate, settings['time_format'])) + ''; + times_row += '' + Q(allday ? rcmail.gettext('all-day','calendar') : format_date(curdate, settings.time_format)) + ''; slots_row += ' '; t += interval * 60000; @@ -1674,10 +1680,10 @@ function rcube_calendar_ui(settings) } me.selected_event.start = start; me.selected_event.end = end; - freebusy_ui.startdate.val($.fullCalendar.formatDate(start, settings['date_format'])); - freebusy_ui.starttime.val($.fullCalendar.formatDate(start, settings['time_format'])); - freebusy_ui.enddate.val($.fullCalendar.formatDate(end, settings['date_format'])); - freebusy_ui.endtime.val($.fullCalendar.formatDate(end, settings['time_format'])); + freebusy_ui.startdate.val(format_date(start, settings.date_format)); + freebusy_ui.starttime.val(format_date(start, settings.time_format)); + freebusy_ui.enddate.val(format_date(end, settings.date_format)); + freebusy_ui.endtime.val(format_date(end, settings.time_format)); freebusy_ui.needsupdate = true; }; @@ -1793,8 +1799,8 @@ function rcube_calendar_ui(settings) if (me.selected_event) { var allday = $('#edit-allday').get(0); me.selected_event.allDay = allday.checked; - me.selected_event.start = parse_datetime(allday.checked ? '12:00' : $('#edit-starttime').val(), $('#edit-startdate').val()); - me.selected_event.end = parse_datetime(allday.checked ? '13:00' : $('#edit-endtime').val(), $('#edit-enddate').val()); + me.selected_event.start = me.parse_datetime(allday.checked ? '12:00' : $('#edit-starttime').val(), $('#edit-startdate').val()); + me.selected_event.end = me.parse_datetime(allday.checked ? '13:00' : $('#edit-endtime').val(), $('#edit-enddate').val()); if (event_attendees) freebusy_ui.needsupdate = true; $('#edit-startdate').data('duration', Math.round((me.selected_event.end.getTime() - me.selected_event.start.getTime()) / 1000)); @@ -2103,8 +2109,7 @@ function rcube_calendar_ui(settings) eventRender: function(event, element, view) { var title = rcmail.get_label(event.status, 'calendar'); element.addClass('status-' + event.status); - element.find('.fc-event-head').hide(); - element.find('.fc-event-title').text(title); + element.find('.fc-title').text(title); element.attr('aria-label', me.event_date_text(event, true) + ': ' + title); } })); @@ -2414,13 +2419,13 @@ function rcube_calendar_ui(settings) event_show_dialog(me.selected_event); } }; - + // add the given date to the RDATE list var add_rdate = function(date) { var li = $('
  • ') .attr('data-value', date2servertime(date)) - .html('' + Q($.fullCalendar.formatDate(date, settings['date_format'])) + '') + .append($('').text(format_date(date, settings.date_format))) .appendTo('#edit-recurrence-rdates'); $('').attr('href', '#del') @@ -2459,19 +2464,27 @@ function rcube_calendar_ui(settings) { me.saving_lock = rcmail.set_busy(true, 'calendar.savingdata'); rcmail.http_post('calendar/event', $.extend({ action:action, e:data }, (add || {}))); - + // render event temporarily into the calendar if ((data.start && data.end) || data.id) { - var event = data.id ? $.extend(fc.fullCalendar('clientEvents', function(e){ return e.id == data.id; })[0], data) : data; + var tmp, event = data.id ? $.extend(fc.fullCalendar('clientEvents', data.id)[0], data) : data; + if (data.start) event.start = data.start; if (data.end) event.end = data.end; - if (data.allday !== undefined) - event.allDay = data.allday; + if (data.allDay !== undefined) + event.allDay = !!data.allDay; // must be boolean for fullcalendar + + // For fullCalendar all-day event's end date must be exclusive + if (event.allDay && data.end && (tmp = moment(data.end)) && tmp.format('Hms') !== '000') { + event.end = moment().year(tmp.year()).month(tmp.month()).date(tmp.date()).hour(0).minute(0).second(0).add(1, 'days'); + } + event.editable = false; event.temp = true; - event.className = 'fc-event-cal-'+data.calendar+' fc-event-temp'; + event.className = ['fc-event-cal-'+data.calendar, 'fc-event-temp']; + fc.fullCalendar(data.id ? 'updateEvent' : 'renderEvent', event); // mark all recurring instances as temp @@ -2480,7 +2493,7 @@ function rcube_calendar_ui(settings) $.each(fc.fullCalendar('clientEvents', function(e){ return e.id == base_id || e.recurrence_id == base_id; }), function(i,ev) { ev.temp = true; ev.editable = false; - event.className += ' fc-event-temp'; + event.className.push('fc-event-temp'); fc.fullCalendar('updateEvent', ev); }); } @@ -2632,7 +2645,7 @@ function rcube_calendar_ui(settings) fc.fullCalendar('refetchEvents'); } }).addClass('event-update-confirm').show(); - + return false; } // show regular confirm box when deleting @@ -2643,16 +2656,10 @@ function rcube_calendar_ui(settings) // do update update_event(action, data); - + return true; }; - var update_agenda_toolbar = function() - { - $('#agenda-listrange').val(fc.fullCalendar('option', 'listRange')); - $('#agenda-listsections').val(fc.fullCalendar('option', 'listSections')); - } - /*** public methods ***/ @@ -2665,65 +2672,6 @@ function rcube_calendar_ui(settings) rcmail.set_busy(false, null, me.saving_lock); }; - // opens calendar day-view in a popup - this.fisheye_view = function(date) - { - $('#fish-eye-view:ui-dialog').dialog('close'); - - // create list of active event sources - var src, cals = {}, sources = []; - for (var id in this.calendars) { - src = $.extend({}, this.calendars[id]); - src.editable = false; - src.url = null; - src.events = []; - - if (src.active) { - cals[id] = src; - sources.push(src); - } - } - - // copy events already loaded - var events = fc.fullCalendar('clientEvents'); - for (var event, i=0; i< events.length; i++) { - event = events[i]; - if (event.source && (src = cals[event.source.id])) { - src.events.push(event); - } - } - - var h = $(window).height() - 50; - var dialog = $('
    ') - .attr('id', 'fish-eye-view') - .dialog({ - modal: true, - width: 680, - height: h, - title: $.fullCalendar.formatDate(date, 'dddd ' + settings['date_long']), - buttons: [{ - text: rcmail.gettext('cancel', 'calendar'), - 'class': 'cancel', - click: function() { $(this).dialog("close"); } - }], - close: function(){ - dialog.dialog("destroy"); - me.fisheye_date = null; - } - }) - .fullCalendar($.extend({}, fullcalendar_defaults, { - defaultView: 'agendaDay', - header: { left: '', center: '', right: '' }, - height: h - 50, - date: date.getDate(), - month: date.getMonth(), - year: date.getFullYear(), - eventSources: sources - })); - - this.fisheye_date = date; - }; - // opens the given calendar in a popup dialog this.quickview = function(id, shift) { @@ -2839,19 +2787,21 @@ function rcube_calendar_ui(settings) this.print_calendars = function(view) { if (!view) view = fc.fullCalendar('getView').name; - var date = fc.fullCalendar('getDate') || new Date(); - var range = fc.fullCalendar('option', 'listRange'); - var sections = fc.fullCalendar('option', 'listSections'); - rcmail.open_window(rcmail.url('print', { view: view, date: date2unixtime(date), range: range, sections: sections, search: this.search_query }), true, true); + var date = fc.fullCalendar('getDate').toDate(); + + rcmail.open_window(rcmail.url('print', { + view: view, + date: date2unixtime(date), + range: settings.agenda_range, + search: this.search_query + }), true, true); }; // public method to bring up the new event dialog this.add_event = function(templ) { if (this.selected_calendar) { var now = new Date(); - var date = fc.fullCalendar('getDate'); - if (typeof date != 'Date') - date = now; + var date = fc.fullCalendar('getDate').toDate(); date.setHours(now.getHours()+1); date.setMinutes(0); var end = new Date(date.getTime()); @@ -2941,9 +2891,10 @@ function rcube_calendar_ui(settings) this.calendar_refresh_source = function(id) { - // got race-conditions fc.currentFetchID when using refetchEvents, + // got race-conditions fc.currentFetchID when using refetchEventSources, // so we remove and add the source instead - // fc.fullCalendar('refetchEvents', me.calendars[id]); + // fc.fullCalendar('refetchEventSources', me.calendars[id]); + // TODO: Check it again with fullcalendar >= 3.9 fc.fullCalendar('removeEventSource', me.calendars[id]); fc.fullCalendar('addEventSource', me.calendars[id]); }; @@ -3093,7 +3044,7 @@ function rcube_calendar_ui(settings) attachmt = $('#event-export-attachments').get(0).checked; if (range == 'custom') - start = date2unixtime(parse_datetime('00:00', $('#event-export-startdate').val())); + start = date2unixtime(me.parse_datetime('00:00', $('#event-export-startdate').val())); else if (range > 0) start = 'today -' + range + ' months'; @@ -3211,7 +3162,7 @@ function rcube_calendar_ui(settings) view.fullCalendar('removeEvents', function(e){ return e._id.indexOf(event._id+'-') == 0; }); } else { - event.source = source; // link with source + event.source = view.fullCalendar('getEventSourceById', source.id); // link with source view.fullCalendar('renderEvent', event); } } @@ -3229,16 +3180,13 @@ function rcube_calendar_ui(settings) return false; } }); - fc.fullCalendar('refetchEvents', source, true); } else if (!source.active) { source.active = true; - fc.fullCalendar('addEventSource', source); $('#rcmlical' + source.id + ' input').prop('checked', true); } - else - fc.fullCalendar('refetchEvents', source, true); + fc.fullCalendar('refetchEventSources', source.id); fetch_counts(); } // add/update single event object @@ -3247,10 +3195,6 @@ function rcube_calendar_ui(settings) event.temp = false; event.editable = 0; - // update fish-eye view - if (this.fisheye_date) - update_view($('#fish-eye-view'), event, source); - // update main view event.editable = source.editable; update_view(fc, event, source); @@ -3261,7 +3205,7 @@ function rcube_calendar_ui(settings) } // refetch all calendars else if (p.refetch) { - fc.fullCalendar('refetchEvents', undefined, true); + fc.fullCalendar('refetchEvents'); fetch_counts(); } }; @@ -3271,8 +3215,8 @@ function rcube_calendar_ui(settings) { var view = fc.fullCalendar('getView'); - query.start = date2unixtime(view.visStart); - query.end = date2unixtime(view.visEnd); + query.start = date2unixtime(view.start.toDate()); + query.end = date2unixtime(view.end.toDate()); if (this.search_query) query.q = this.search_query; @@ -3327,7 +3271,7 @@ function rcube_calendar_ui(settings) var query = { view: fc.fullCalendar('getView').name }, date = fc.fullCalendar('getDate'); if (date) - query.date = date2unixtime(date); + query.date = date2unixtime(date.toDate()); rcmail.redirect(rcmail.url('', query)); } @@ -3337,7 +3281,7 @@ function rcube_calendar_ui(settings) var query = { view: current_view }, date = fc.fullCalendar('getDate'); if (date) - query.date = date2unixtime(date); + query.date = date2unixtime(date.toDate()); if (window.history.replaceState) window.history.replaceState({}, document.title, rcmail.url('', query).replace('&_action=', '')); @@ -3367,12 +3311,11 @@ function rcube_calendar_ui(settings) if (this._search_message) rcmail.hide_message(this._search_message); - for (var sid in this.calendars) { - if (this.calendars[sid]) { - this.calendars[sid].url = this.calendars[sid].url.replace(/&q=.+/, '') + '&q=' + urlencode(q); - sources.push(sid); - } - } + $.each(fc.fullCalendar('getEventSources'), function() { + this.url = this.url.replace(/&q=.+/, '') + '&q=' + urlencode(q); + me.calendars[this.id].url = this.url; + sources.push(this.id); + }); id += '@'+sources.join(','); // ignore if query didn't change @@ -3388,12 +3331,8 @@ function rcube_calendar_ui(settings) this.search_query = q; // change to list view - fc.fullCalendar('option', 'listSections', 'month') - .fullCalendar('option', 'listRange', Math.max(60, settings['agenda_range'])) - .fullCalendar('changeView', 'table'); - - update_agenda_toolbar(); - + fc.fullCalendar('changeView', 'list'); + // refetch events with new url (if not already triggered by changeView) if (!this.is_loading) fc.fullCalendar('refetchEvents'); @@ -3407,105 +3346,34 @@ function rcube_calendar_ui(settings) this.reset_quicksearch = function() { $(rcmail.gui_objects.qsearchbox).val(''); - + if (this._search_message) rcmail.hide_message(this._search_message); - + if (this.search_request) { - // hide bottom links of agenda view - fc.find('.fc-list-content > .fc-listappend').hide(); - - // restore original event sources and view mode from fullcalendar - fc.fullCalendar('option', 'listSections', settings['agenda_sections']) - .fullCalendar('option', 'listRange', settings['agenda_range']); - - update_agenda_toolbar(); - - for (var sid in this.calendars) { - if (this.calendars[sid]) - this.calendars[sid].url = this.calendars[sid].url.replace(/&q=.+/, ''); - } - if (this.default_view) - fc.fullCalendar('changeView', this.default_view); - - if (!this.is_loading) - fc.fullCalendar('refetchEvents'); - + $.each(fc.fullCalendar('getEventSources'), function() { + this.url = this.url.replace(/&q=.+/, ''); + me.calendars[this.id].url = this.url; + }); + this.search_request = this.search_query = null; + + fc.fullCalendar('refetchEvents'); } }; // callback if all sources have been fetched from server - this.events_loaded = function(count) + this.events_loaded = function() { - var addlinks, append = ''; - - // enhance list view when searching - if (this.search_request) { - if (!count) { - this._search_message = rcmail.display_message(rcmail.gettext('searchnoresults', 'calendar'), 'notice'); - append = '
    ' + rcmail.gettext('searchnoresults', 'calendar') + '
    '; - } - append += ''; - addlinks = true; + if (this.search_request && !fc.fullCalendar('clientEvents').length) { + this._search_message = rcmail.display_message(rcmail.gettext('searchnoresults', 'calendar'), 'notice'); } - - if (fc.fullCalendar('getView').name == 'table') { - var elastic = $('#calendar').data('elastic-mode'); - var container = elastic ? $('#searchcontrols') : fc.find('.fc-list-content > .fc-listappend'); - if (append) { - if (!container.length) - container = $('
    ').appendTo(fc.find('.fc-list-content')); - container.html(append).show(); - } - else if (container.length) - container.hide(); - - // add links to adjust search date range - if (addlinks) { - var lc = container.find('.fc-bottomlinks'); - - if (elastic) { - $('
    ').attr({href: '#', 'class': 'button icon tools'}) - .append($('').text(rcmail.gettext('showtools'))) - .prependTo('#searchcontrols') - .click(function() { - $(this).attr('title', rcmail.gettext($('#searchcontrols').toggleClass('open').is('.open') ? 'hidetools' : 'showtools')); - }); - } - - $('').attr({href: '#', 'class': 'button prev'}) - .append($('').text(rcmail.gettext(elastic ? 'earlierevents' : 'searchearlierdates', 'calendar'))) - .appendTo(lc) - .click(function() { - fc.fullCalendar('incrementDate', 0, -1, 0); - }); - - lc.append(" "); - - $('').attr({href: '#', 'class': 'button next'}) - .append($('').text(rcmail.gettext(elastic ? 'laterevents' : 'searchlaterdates', 'calendar'))) - .appendTo(lc) - .click(function() { - var range = fc.fullCalendar('option', 'listRange'); - if (range < 90) { - fc.fullCalendar('option', 'listRange', fc.fullCalendar('option', 'listRange') + 30).fullCalendar('render'); - update_agenda_toolbar(); - } - else - fc.fullCalendar('incrementDate', 0, 1, 0); - }); - } - } - - if (this.fisheye_date) - this.fisheye_view(this.fisheye_date); }; // adjust calendar view size this.view_resize = function() { - var footer = fc.fullCalendar('getView').name == 'table' ? $('#agendaoptions').outerHeight() : 0; + var footer = fc.fullCalendar('getView').name == 'list' ? $('#agendaoptions').outerHeight() : 0; fc.fullCalendar('option', 'height', $('#calendar').height() - footer); }; @@ -3521,7 +3389,6 @@ function rcube_calendar_ui(settings) this.selected_calendar = id; rcmail.update_state({source: id}); - rcmail.enable_command('addevent', this.calendars[id] && this.calendars[id].editable); }; @@ -3532,21 +3399,22 @@ function rcube_calendar_ui(settings) me.calendars[id] = $.extend({ url: rcmail.url('calendar/load_events', { source: id }), - className: 'fc-event-cal-'+id, + className: ['fc-event-cal-' + id], id: id }, cal); // choose black text color when background is bright, white otherwise if (color = settings.event_coloring % 2 ? '' : '#' + cal.color) { + me.calendars[id].color = color; + me.calendars[id].textColor = 'white'; + if (/^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i.test(color)) { // use information about brightness calculation found at // http://javascriptrules.com/2009/08/05/css-color-brightness-contrast-using-javascript/ brightness = (parseInt(RegExp.$1, 16) * 299 + parseInt(RegExp.$2, 16) * 587 + parseInt(RegExp.$3, 16) * 114) / 1000; if (brightness > 125) - me.calendars[id].textColor = 'black'; + me.calendars[id].textColor = '#222'; } - - me.calendars[id].color = color; } if (fc && (cal.active || cal.subscribed)) { @@ -3741,10 +3609,10 @@ function rcube_calendar_ui(settings) if (window.UI && UI.pretty_checkbox) { $(rcmail.gui_objects.calendarslist).find('input[type=checkbox]').each(function() { UI.pretty_checkbox($(this).addClass('flex-checkbox')); - }); - calendars_list.addEventListener('add-item', function(prop) { - UI.pretty_checkbox($(prop.li).find('input').addClass('flex-checkbox')); - }); + }); + calendars_list.addEventListener('add-item', function(prop) { + UI.pretty_checkbox($(prop.li).find('input').addClass('flex-checkbox')); + }); } // create list of event sources AKA calendars @@ -3767,7 +3635,7 @@ function rcube_calendar_ui(settings) if (rcmail.env.itip_events && rcmail.env.itip_events.length) { me.calendars['--invitation--itip'] = { events: rcmail.env.itip_events, - className: 'fc-event-cal---invitation--itip', + className: ['fc-event-cal---invitation--itip'], color: '#fff', textColor: '#333', editable: false, @@ -3782,91 +3650,79 @@ function rcube_calendar_ui(settings) header: { right: 'prev,next today', center: 'title', - left: 'agendaDay,agendaWeek,month,table' + left: 'agendaDay,agendaWeek,month,list' }, - date: viewdate.getDate(), - month: viewdate.getMonth(), - year: viewdate.getFullYear(), + defaultDate: viewdate, height: $('#calendar').height(), eventSources: event_sources, selectable: true, selectHelper: false, loading: function(isLoading) { me.is_loading = isLoading; - this._rc_loading = rcmail.set_busy(isLoading, 'loading', this._rc_loading); - // trigger callback + this._rc_loading = rcmail.set_busy(isLoading, me.search_request ? 'searching' : 'loading', this._rc_loading); + // trigger callback (using timeout, otherwise clientEvents is always empty) if (!isLoading) - me.events_loaded($(this).fullCalendar('clientEvents').length); + setTimeout(function() { me.events_loaded(); }, 20); }, // callback for date range selection - select: function(start, end, allDay, e, view) { - var range_select = (!allDay || start.getDate() != end.getDate()) + select: function(start, end, e, view) { + var range_select = (start.hasTime() || start != end) if (dialog_check(e) && range_select) - event_edit_dialog('new', { start:start, end:end, allDay:allDay, calendar:me.selected_calendar }); + event_edit_dialog('new', { start:start, end:end, allDay:!start.hasTime(), calendar:me.selected_calendar }); if (range_select || ignore_click) view.calendar.unselect(); }, // callback for clicks in all-day box - dayClick: function(date, allDay, e, view) { + dayClick: function(date, e, view) { var now = new Date().getTime(); - if (now - day_clicked_ts < 400 && day_clicked == date.getTime()) { // emulate double-click on day - var enddate = new Date(); enddate.setTime(date.getTime() + DAY_MS - 60000); - return event_edit_dialog('new', { start:date, end:enddate, allDay:allDay, calendar:me.selected_calendar }); + if (now - day_clicked_ts < 400 && day_clicked == date.toDate().getTime()) { // emulate double-click on day + var enddate = new Date(); + if (date.hasTime()) + enddate.setTime(date.toDate().getTime() + DAY_MS - 60000); + return event_edit_dialog('new', { start:date, end:enddate, allDay:!date.hasTime(), calendar:me.selected_calendar }); } - + if (!ignore_click) { view.calendar.gotoDate(date); - if (day_clicked && new Date(day_clicked).getMonth() != date.getMonth()) - view.calendar.select(date, date, allDay); + if (day_clicked && new Date(day_clicked).getMonth() != date.toDate().getMonth()) + view.calendar.select(date, date); } - day_clicked = date.getTime(); + day_clicked = date.toDate().getTime(); day_clicked_ts = now; }, // callback when an event was dragged and finally dropped - eventDrop: function(event, dayDelta, minuteDelta, allDay, revertFunc) { - if (event.end == null || event.end.getTime() < event.start.getTime()) { - event.end = new Date(event.start.getTime() + (allDay ? DAY_MS : HOUR_MS)); + eventDrop: function(event, delta, revertFunc) { + if (!event.end || event.end.diff(event.start) < 0) { + if (event.allDay) + event.end = moment(event.start).hour(13).minute(0).second(0); + else + event.end = moment(event.start).add(2, 'hours'); } - // moved to all-day section: set times to 12:00 - 13:00 - if (allDay && !event.allDay) { - event.start.setHours(12); - event.start.setMinutes(0); - event.start.setSeconds(0); - event.end.setHours(13); - event.end.setMinutes(0); - event.end.setSeconds(0); + else if (event.allDay) { + event.end.subtract(1, 'days').hour(13); } - // moved from all-day section: set times to working hours - else if (event.allDay && !allDay) { - var newstart = event.start.getTime(); - revertFunc(); // revert to get original duration - var numdays = Math.max(1, Math.round((event.end.getTime() - event.start.getTime()) / DAY_MS)) - 1; - event.start = new Date(newstart); - event.end = new Date(newstart + numdays * DAY_MS); - event.end.setHours(settings['work_end'] || 18); - event.end.setMinutes(0); - - if (event.end.getTime() < event.start.getTime()) - event.end = new Date(newstart + HOUR_MS); - } - + + if (event.allDay) + event.start.hour(12); + // send move request to server var data = { id: event.id, calendar: event.calendar, start: date2servertime(event.start), end: date2servertime(event.end), - allday: allDay?1:0 + allDay: event.allDay?1:0 }; + update_event_confirm('move', event, data); }, // callback for event resizing eventResize: function(event, delta) { // sanitize event dates - if (event.allDay) - event.start.setHours(12); - if (!event.end || event.end.getTime() < event.start.getTime()) - event.end = new Date(event.start.getTime() + HOUR_MS); + if (event.allDay) { + event.start.hours(12); + event.end.hour(13).subtract(1, 'days'); + } // send resize request to server var data = { @@ -3874,39 +3730,53 @@ function rcube_calendar_ui(settings) calendar: event.calendar, start: date2servertime(event.start), end: date2servertime(event.end), - allday: event.allDay?1:0 + allDay: event.allDay?1:0 }; + update_event_confirm('resize', event, data); }, - viewDisplay: function(view) { - $('#agendaoptions')[view.name == 'table' ? 'show' : 'hide'](); + viewRender: function(view, element) { + $('#agendaoptions')[view.name == 'list' ? 'show' : 'hide'](); if (minical) { - window.setTimeout(function(){ minical.datepicker('setDate', fc.fullCalendar('getDate')); }, exec_deferred); + window.setTimeout(function(){ minical.datepicker('setDate', fc.fullCalendar('getDate').toDate()); }, exec_deferred); if (view.name != current_view) me.view_resize(); current_view = view.name; me.update_state(); } + + if (view.name == 'list') { + var viewStart = moment(view.start); + + $('#calendar .fc-prev-button').off('click').on('click', function() { + fc.fullCalendar('gotoDate', viewStart.subtract(settings.agenda_range, 'days')); + }); + $('#calendar .fc-next-button').off('click').on('click', function() { + fc.fullCalendar('gotoDate', viewStart.add(settings.agenda_range, 'days')); + }); + } }, - viewRender: function(view) { - if (fc && view.name == 'month') - fc.fullCalendar('option', 'maxHeight', Math.floor((view.element.parent().height()-18) / 6) - 35); + eventAfterAllRender: function(view) { + if (view.name == 'list') { + // Fix colspan of headers after we added Location column + fc.find('tr.fc-list-heading > td').attr('colspan', 4); + } } })); // if start date is changed, shift end date according to initial duration var shift_enddate = function(dateText) { - var newstart = parse_datetime('0', dateText); + var newstart = me.parse_datetime('0', dateText); var newend = new Date(newstart.getTime() + $('#edit-startdate').data('duration') * 1000); - $('#edit-enddate').val($.fullCalendar.formatDate(newend, me.settings['date_format'])); + $('#edit-enddate').val(format_date(newend, me.settings.date_format)); event_times_changed(); }; // Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. // Uses the default $.datepicker.iso8601Week() function but takes firstDay setting into account. // This is a temporary fix until http://bugs.jqueryui.com/ticket/8420 is resolved. - var iso8601Week = datepicker_settings.calculateWeek = function(date) { - var mondayOffset = Math.abs(1 - datepicker_settings.firstDay); + var iso8601Week = me.datepicker_settings.calculateWeek = function(date) { + var mondayOffset = Math.abs(1 - me.datepicker_settings.firstDay); return $.datepicker.iso8601Week(new Date(date.getTime() + mondayOffset * 86400000)); }; @@ -3921,14 +3791,15 @@ function rcube_calendar_ui(settings) }; // initialize small calendar widget using jQuery UI datepicker - minical = $('#datepicker').datepicker($.extend(datepicker_settings, { + minical = $('#datepicker').datepicker($.extend(me.datepicker_settings, { inline: true, changeMonth: true, changeYear: true, onSelect: function(dateText, inst) { ignore_click = true; - var d = minical.datepicker('getDate'); //parse_datetime('0:0', dateText); - fc.fullCalendar('gotoDate', d).fullCalendar('select', d, d, true); + var d = minical.datepicker('getDate'); + fc.fullCalendar('gotoDate', d) + fc.fullCalendar('select', d, d); setTimeout(function() { pretty_select($('select', minical)); }, 25); }, onChangeMonthYear: function(year, month, inst) { @@ -3936,9 +3807,13 @@ function rcube_calendar_ui(settings) setTimeout(function() { pretty_select($('select', minical)); }, 25); }, beforeShowDay: function(date) { + // TODO: this pretty_select() calls should be implemented in a different way setTimeout(function() { pretty_select($('select', minical)); }, 25); - var view = fc.fullCalendar('getView'); - var active = view.visStart && date.getTime() >= view.visStart.getTime() && date.getTime() < view.visEnd.getTime(); + + var view = fc.fullCalendar('getView'), + dt = moment(date).format('YYYYMMDD'), + active = view.start && view.start.format('YYYYMMDD') <= dt && view.end.format('YYYYMMDD') > dt; + return [ true, (active ? 'ui-datepicker-activerange ui-datepicker-active-' + view.name : ''), '']; } })) // set event handler for clicks on calendar week cell of the datepicker widget @@ -3951,7 +3826,7 @@ function rcube_calendar_ui(settings) if (minical.data('year')) base_date.setYear(minical.data('year')); base_date.setHours(12); - base_date.setDate(base_date.getDate() - ((base_date.getDay() + 6) % 7) + datepicker_settings.firstDay); + base_date.setDate(base_date.getDate() - ((base_date.getDay() + 6) % 7) + me.datepicker_settings.firstDay); var base_kw = iso8601Week(base_date), target_kw = parseInt(cell.html()), wdiff = target_kw - base_kw; @@ -3960,9 +3835,10 @@ function rcube_calendar_ui(settings) else if (wdiff < -10) base_date.setYear(base_date.getFullYear() + 1); // select monday of the chosen calendar week - var day_off = base_date.getDay() - datepicker_settings.firstDay, + var day_off = base_date.getDay() - me.datepicker_settings.firstDay, date = new Date(base_date.getTime() - day_off * DAY_MS + wdiff * 7 * DAY_MS); - fc.fullCalendar('gotoDate', date).fullCalendar('setDate', date).fullCalendar('changeView', 'agendaWeek'); + + fc.fullCalendar('changeView', 'agendaWeek', date); minical.datepicker('setDate', date); setTimeout(function() { pretty_select($('select', minical)); }, 25); } @@ -4011,11 +3887,11 @@ function rcube_calendar_ui(settings) $('#edit-recurrence-syncstart').hide(); }; - $('#eventedit:not([data-notabs])').tabs({activate: tab_change}); // Larry - $('#eventedit a.nav-link').on('show.bs.tab', tab_change); // Elastic + $('#eventedit:not([data-notabs])').tabs({activate: tab_change}); // Larry + $('#eventedit a.nav-link').on('show.bs.tab', tab_change); // Elastic - $('#edit-enddate').datepicker(datepicker_settings); - $('#edit-startdate').datepicker(datepicker_settings).datepicker('option', 'onSelect', shift_enddate).change(function(){ shift_enddate(this.value); }); + $('#edit-enddate').datepicker(me.datepicker_settings); + $('#edit-startdate').datepicker(me.datepicker_settings).datepicker('option', 'onSelect', shift_enddate).change(function(){ shift_enddate(this.value); }); $('#edit-enddate').datepicker('option', 'onSelect', event_times_changed).change(event_times_changed); $('#edit-allday').click(function(){ $('#edit-starttime, #edit-endtime')[(this.checked?'hide':'show')](); event_times_changed(); }); @@ -4030,10 +3906,10 @@ function rcube_calendar_ui(settings) // adjust end time when changing start $('#edit-starttime').change(function(e) { var dstart = $('#edit-startdate'), - newstart = parse_datetime(this.value, dstart.val()), + newstart = me.parse_datetime(this.value, dstart.val()), newend = new Date(newstart.getTime() + dstart.data('duration') * 1000); - $('#edit-endtime').val($.fullCalendar.formatDate(newend, me.settings['time_format'])); - $('#edit-enddate').val($.fullCalendar.formatDate(newend, me.settings['date_format'])); + $('#edit-endtime').val(format_date(newend, me.settings.time_format)); + $('#edit-enddate').val(format_date(newend, me.settings.date_format)); event_times_changed(); }); @@ -4052,7 +3928,7 @@ function rcube_calendar_ui(settings) } }); - $('#event-export-startdate').datepicker(datepicker_settings); + $('#event-export-startdate').datepicker(me.datepicker_settings); // init attendees autocompletion var ac_props; @@ -4176,16 +4052,10 @@ function rcube_calendar_ui(settings) }); $('#agenda-listrange').change(function(e){ - settings['agenda_range'] = parseInt($(this).val()); - fc.fullCalendar('option', 'listRange', settings['agenda_range']).fullCalendar('render'); + settings.agenda_range = parseInt($(this).val()); + fc.fullCalendar('changeView', 'list'); // TODO: save new settings in prefs - }).val(settings['agenda_range']); - - $('#agenda-listsections').change(function(e){ - settings['agenda_sections'] = $(this).val(); - fc.fullCalendar('option', 'listSections', settings['agenda_sections']).fullCalendar('render'); - // TODO: save new settings in prefs - }).val(fc.fullCalendar('option', 'listSections')); + }).val(settings.agenda_range); // hide event dialog when clicking somewhere into document $(document).bind('mousedown', dialog_check); @@ -4199,10 +4069,6 @@ function rcube_calendar_ui(settings) // fetch counts for some calendars fetch_counts(); - // add proprietary css styles if not IE - if (!bw.ie) - $('div.fc-content').addClass('rcube-fc-content'); - // Save-as-event dialog content if (rcmail.env.action == 'dialog-ui') { var date = new Date(), event = {allDay: false, calendar: me.selected_calendar}; @@ -4324,10 +4190,10 @@ window.rcmail && rcmail.addEventListener('init', function(evt) { // Elastic mods if ($('#calendar').data('elastic-mode')) { - var selector = $('
    ').appendTo('.fc-header-left'), - nav = $('
    ').appendTo('.fc-header-right'); + var selector = $('
    ').appendTo('.fc-header-toolbar > .fc-left'), + nav = $('
    ').appendTo('.fc-header-toolbar > .fc-right'); - $('.fc-header-left > span').each(function() { + $('.fc-header-toolbar > .fc-left button').each(function() { var new_btn, cl = 'btn btn-secondary', btn = $(this), activate = function(button) { selector.children('.active').removeClass('active'); @@ -4352,19 +4218,19 @@ window.rcmail && rcmail.addEventListener('init', function(evt) { }); $.each(['prev', 'today', 'next'], function() { - var btn = $('.fc-header-right').find('.fc-button-' + this); - $('') + .click(function (ev) { + // don't process clicks for disabled buttons + if (!buttonEl.hasClass(theme.getClass('stateDisabled'))) { + buttonClick(ev); + // after the click action, if the button becomes the "active" tab, or disabled, + // it should never have a hover class, so remove it now. + if (buttonEl.hasClass(theme.getClass('stateActive')) || + buttonEl.hasClass(theme.getClass('stateDisabled'))) { + buttonEl.removeClass(theme.getClass('stateHover')); + } + } + }) + .mousedown(function () { + // the *down* effect (mouse pressed in). + // only on buttons that are not the "active" tab, or disabled + buttonEl + .not('.' + theme.getClass('stateActive')) + .not('.' + theme.getClass('stateDisabled')) + .addClass(theme.getClass('stateDown')); + }) + .mouseup(function () { + // undo the *down* effect + buttonEl.removeClass(theme.getClass('stateDown')); + }) + .hover(function () { + // the *hover* effect. + // only on buttons that are not the "active" tab, or disabled + buttonEl + .not('.' + theme.getClass('stateActive')) + .not('.' + theme.getClass('stateDisabled')) + .addClass(theme.getClass('stateHover')); + }, function () { + // undo the *hover* effect + buttonEl + .removeClass(theme.getClass('stateHover')) + .removeClass(theme.getClass('stateDown')); // if mouseleave happens before mouseup + }); + groupChildren = groupChildren.add(buttonEl); + } + } + }); + if (isOnlyButtons) { + groupChildren + .first().addClass(theme.getClass('cornerLeft')).end() + .last().addClass(theme.getClass('cornerRight')).end(); + } + if (groupChildren.length > 1) { + groupEl = $('
    '); + if (isOnlyButtons) { + groupEl.addClass(theme.getClass('buttonGroup')); + } + groupEl.append(groupChildren); + sectionEl.append(groupEl); + } + else { + sectionEl.append(groupChildren); // 1 or 0 children + } + }); + } + return sectionEl; + }; + Toolbar.prototype.updateTitle = function (text) { + if (this.el) { + this.el.find('h2').text(text); + } + }; + Toolbar.prototype.activateButton = function (buttonName) { + if (this.el) { + this.el.find('.fc-' + buttonName + '-button') + .addClass(this.calendar.theme.getClass('stateActive')); + } + }; + Toolbar.prototype.deactivateButton = function (buttonName) { + if (this.el) { + this.el.find('.fc-' + buttonName + '-button') + .removeClass(this.calendar.theme.getClass('stateActive')); + } + }; + Toolbar.prototype.disableButton = function (buttonName) { + if (this.el) { + this.el.find('.fc-' + buttonName + '-button') + .prop('disabled', true) + .addClass(this.calendar.theme.getClass('stateDisabled')); + } + }; + Toolbar.prototype.enableButton = function (buttonName) { + if (this.el) { + this.el.find('.fc-' + buttonName + '-button') + .prop('disabled', false) + .removeClass(this.calendar.theme.getClass('stateDisabled')); + } + }; + Toolbar.prototype.getViewsWithButtons = function () { + return this.viewsWithButtons; + }; + return Toolbar; +}()); +exports.default = Toolbar; + + +/***/ }), +/* 240 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = __webpack_require__(2); +var $ = __webpack_require__(3); +var util_1 = __webpack_require__(4); +var options_1 = __webpack_require__(32); +var locale_1 = __webpack_require__(31); +var Model_1 = __webpack_require__(48); +var OptionsManager = /** @class */ (function (_super) { + tslib_1.__extends(OptionsManager, _super); + function OptionsManager(_calendar, overrides) { + var _this = _super.call(this) || this; + _this._calendar = _calendar; + _this.overrides = $.extend({}, overrides); // make a copy + _this.dynamicOverrides = {}; + _this.compute(); + return _this; + } + OptionsManager.prototype.add = function (newOptionHash) { + var optionCnt = 0; + var optionName; + this.recordOverrides(newOptionHash); // will trigger this model's watchers + for (optionName in newOptionHash) { + optionCnt++; + } + // special-case handling of single option change. + // if only one option change, `optionName` will be its name. + if (optionCnt === 1) { + if (optionName === 'height' || optionName === 'contentHeight' || optionName === 'aspectRatio') { + this._calendar.updateViewSize(true); // isResize=true + return; + } + else if (optionName === 'defaultDate') { + return; // can't change date this way. use gotoDate instead + } + else if (optionName === 'businessHours') { + return; // this model already reacts to this + } + else if (/^(event|select)(Overlap|Constraint|Allow)$/.test(optionName)) { + return; // doesn't affect rendering. only interactions. + } + else if (optionName === 'timezone') { + this._calendar.view.flash('initialEvents'); + return; + } + } + // catch-all. rerender the header and footer and rebuild/rerender the current view + this._calendar.renderHeader(); + this._calendar.renderFooter(); + // even non-current views will be affected by this option change. do before rerender + // TODO: detangle + this._calendar.viewsByType = {}; + this._calendar.reinitView(); + }; + // Computes the flattened options hash for the calendar and assigns to `this.options`. + // Assumes this.overrides and this.dynamicOverrides have already been initialized. + OptionsManager.prototype.compute = function () { + var locale; + var localeDefaults; + var isRTL; + var dirDefaults; + var rawOptions; + locale = util_1.firstDefined(// explicit locale option given? + this.dynamicOverrides.locale, this.overrides.locale); + localeDefaults = locale_1.localeOptionHash[locale]; + if (!localeDefaults) { + locale = options_1.globalDefaults.locale; + localeDefaults = locale_1.localeOptionHash[locale] || {}; + } + isRTL = util_1.firstDefined(// based on options computed so far, is direction RTL? + this.dynamicOverrides.isRTL, this.overrides.isRTL, localeDefaults.isRTL, options_1.globalDefaults.isRTL); + dirDefaults = isRTL ? options_1.rtlDefaults : {}; + this.dirDefaults = dirDefaults; + this.localeDefaults = localeDefaults; + rawOptions = options_1.mergeOptions([ + options_1.globalDefaults, + dirDefaults, + localeDefaults, + this.overrides, + this.dynamicOverrides + ]); + locale_1.populateInstanceComputableOptions(rawOptions); // fill in gaps with computed options + this.reset(rawOptions); + }; + // stores the new options internally, but does not rerender anything. + OptionsManager.prototype.recordOverrides = function (newOptionHash) { + var optionName; + for (optionName in newOptionHash) { + this.dynamicOverrides[optionName] = newOptionHash[optionName]; + } + this._calendar.viewSpecManager.clearCache(); // the dynamic override invalidates the options in this cache, so just clear it + this.compute(); // this.options needs to be recomputed after the dynamic override + }; + return OptionsManager; +}(Model_1.default)); +exports.default = OptionsManager; + + +/***/ }), +/* 241 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var moment = __webpack_require__(0); +var $ = __webpack_require__(3); +var ViewRegistry_1 = __webpack_require__(22); +var util_1 = __webpack_require__(4); +var options_1 = __webpack_require__(32); +var locale_1 = __webpack_require__(31); +var ViewSpecManager = /** @class */ (function () { + function ViewSpecManager(optionsManager, _calendar) { + this.optionsManager = optionsManager; + this._calendar = _calendar; + this.clearCache(); + } + ViewSpecManager.prototype.clearCache = function () { + this.viewSpecCache = {}; + }; + // Gets information about how to create a view. Will use a cache. + ViewSpecManager.prototype.getViewSpec = function (viewType) { + var cache = this.viewSpecCache; + return cache[viewType] || (cache[viewType] = this.buildViewSpec(viewType)); + }; + // Given a duration singular unit, like "week" or "day", finds a matching view spec. + // Preference is given to views that have corresponding buttons. + ViewSpecManager.prototype.getUnitViewSpec = function (unit) { + var viewTypes; + var i; + var spec; + if ($.inArray(unit, util_1.unitsDesc) !== -1) { + // put views that have buttons first. there will be duplicates, but oh well + viewTypes = this._calendar.header.getViewsWithButtons(); // TODO: include footer as well? + $.each(ViewRegistry_1.viewHash, function (viewType) { + viewTypes.push(viewType); + }); + for (i = 0; i < viewTypes.length; i++) { + spec = this.getViewSpec(viewTypes[i]); + if (spec) { + if (spec.singleUnit === unit) { + return spec; + } + } + } + } + }; + // Builds an object with information on how to create a given view + ViewSpecManager.prototype.buildViewSpec = function (requestedViewType) { + var viewOverrides = this.optionsManager.overrides.views || {}; + var specChain = []; // for the view. lowest to highest priority + var defaultsChain = []; // for the view. lowest to highest priority + var overridesChain = []; // for the view. lowest to highest priority + var viewType = requestedViewType; + var spec; // for the view + var overrides; // for the view + var durationInput; + var duration; + var unit; + // iterate from the specific view definition to a more general one until we hit an actual View class + while (viewType) { + spec = ViewRegistry_1.viewHash[viewType]; + overrides = viewOverrides[viewType]; + viewType = null; // clear. might repopulate for another iteration + if (typeof spec === 'function') { + spec = { 'class': spec }; + } + if (spec) { + specChain.unshift(spec); + defaultsChain.unshift(spec.defaults || {}); + durationInput = durationInput || spec.duration; + viewType = viewType || spec.type; + } + if (overrides) { + overridesChain.unshift(overrides); // view-specific option hashes have options at zero-level + durationInput = durationInput || overrides.duration; + viewType = viewType || overrides.type; + } + } + spec = util_1.mergeProps(specChain); + spec.type = requestedViewType; + if (!spec['class']) { + return false; + } + // fall back to top-level `duration` option + durationInput = durationInput || + this.optionsManager.dynamicOverrides.duration || + this.optionsManager.overrides.duration; + if (durationInput) { + duration = moment.duration(durationInput); + if (duration.valueOf()) { + unit = util_1.computeDurationGreatestUnit(duration, durationInput); + spec.duration = duration; + spec.durationUnit = unit; + // view is a single-unit duration, like "week" or "day" + // incorporate options for this. lowest priority + if (duration.as(unit) === 1) { + spec.singleUnit = unit; + overridesChain.unshift(viewOverrides[unit] || {}); + } + } + } + spec.defaults = options_1.mergeOptions(defaultsChain); + spec.overrides = options_1.mergeOptions(overridesChain); + this.buildViewSpecOptions(spec); + this.buildViewSpecButtonText(spec, requestedViewType); + return spec; + }; + // Builds and assigns a view spec's options object from its already-assigned defaults and overrides + ViewSpecManager.prototype.buildViewSpecOptions = function (spec) { + var optionsManager = this.optionsManager; + spec.options = options_1.mergeOptions([ + options_1.globalDefaults, + spec.defaults, + optionsManager.dirDefaults, + optionsManager.localeDefaults, + optionsManager.overrides, + spec.overrides, + optionsManager.dynamicOverrides // dynamically set via setter. highest precedence + ]); + locale_1.populateInstanceComputableOptions(spec.options); + }; + // Computes and assigns a view spec's buttonText-related options + ViewSpecManager.prototype.buildViewSpecButtonText = function (spec, requestedViewType) { + var optionsManager = this.optionsManager; + // given an options object with a possible `buttonText` hash, lookup the buttonText for the + // requested view, falling back to a generic unit entry like "week" or "day" + function queryButtonText(options) { + var buttonText = options.buttonText || {}; + return buttonText[requestedViewType] || + // view can decide to look up a certain key + (spec.buttonTextKey ? buttonText[spec.buttonTextKey] : null) || + // a key like "month" + (spec.singleUnit ? buttonText[spec.singleUnit] : null); + } + // highest to lowest priority + spec.buttonTextOverride = + queryButtonText(optionsManager.dynamicOverrides) || + queryButtonText(optionsManager.overrides) || // constructor-specified buttonText lookup hash takes precedence + spec.overrides.buttonText; // `buttonText` for view-specific options is a string + // highest to lowest priority. mirrors buildViewSpecOptions + spec.buttonTextDefault = + queryButtonText(optionsManager.localeDefaults) || + queryButtonText(optionsManager.dirDefaults) || + spec.defaults.buttonText || // a single string. from ViewSubclass.defaults + queryButtonText(options_1.globalDefaults) || + (spec.duration ? this._calendar.humanizeDuration(spec.duration) : null) || // like "3 days" + requestedViewType; // fall back to given view name + }; + return ViewSpecManager; +}()); +exports.default = ViewSpecManager; + + +/***/ }), +/* 242 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var $ = __webpack_require__(3); +var util_1 = __webpack_require__(4); +var EventPeriod_1 = __webpack_require__(243); +var ArrayEventSource_1 = __webpack_require__(52); +var EventSource_1 = __webpack_require__(6); +var EventSourceParser_1 = __webpack_require__(38); +var SingleEventDef_1 = __webpack_require__(13); +var EventInstanceGroup_1 = __webpack_require__(18); +var EmitterMixin_1 = __webpack_require__(11); +var ListenerMixin_1 = __webpack_require__(7); +var EventManager = /** @class */ (function () { + function EventManager(calendar) { + this.calendar = calendar; + this.stickySource = new ArrayEventSource_1.default(calendar); + this.otherSources = []; + } + EventManager.prototype.requestEvents = function (start, end, timezone, force) { + if (force || + !this.currentPeriod || + !this.currentPeriod.isWithinRange(start, end) || + timezone !== this.currentPeriod.timezone) { + this.setPeriod(// will change this.currentPeriod + new EventPeriod_1.default(start, end, timezone)); + } + return this.currentPeriod.whenReleased(); + }; + // Source Adding/Removing + // ----------------------------------------------------------------------------------------------------------------- + EventManager.prototype.addSource = function (eventSource) { + this.otherSources.push(eventSource); + if (this.currentPeriod) { + this.currentPeriod.requestSource(eventSource); // might release + } + }; + EventManager.prototype.removeSource = function (doomedSource) { + util_1.removeExact(this.otherSources, doomedSource); + if (this.currentPeriod) { + this.currentPeriod.purgeSource(doomedSource); // might release + } + }; + EventManager.prototype.removeAllSources = function () { + this.otherSources = []; + if (this.currentPeriod) { + this.currentPeriod.purgeAllSources(); // might release + } + }; + // Source Refetching + // ----------------------------------------------------------------------------------------------------------------- + EventManager.prototype.refetchSource = function (eventSource) { + var currentPeriod = this.currentPeriod; + if (currentPeriod) { + currentPeriod.freeze(); + currentPeriod.purgeSource(eventSource); + currentPeriod.requestSource(eventSource); + currentPeriod.thaw(); + } + }; + EventManager.prototype.refetchAllSources = function () { + var currentPeriod = this.currentPeriod; + if (currentPeriod) { + currentPeriod.freeze(); + currentPeriod.purgeAllSources(); + currentPeriod.requestSources(this.getSources()); + currentPeriod.thaw(); + } + }; + // Source Querying + // ----------------------------------------------------------------------------------------------------------------- + EventManager.prototype.getSources = function () { + return [this.stickySource].concat(this.otherSources); + }; + // like querySources, but accepts multple match criteria (like multiple IDs) + EventManager.prototype.multiQuerySources = function (matchInputs) { + // coerce into an array + if (!matchInputs) { + matchInputs = []; + } + else if (!$.isArray(matchInputs)) { + matchInputs = [matchInputs]; + } + var matchingSources = []; + var i; + // resolve raw inputs to real event source objects + for (i = 0; i < matchInputs.length; i++) { + matchingSources.push.apply(// append + matchingSources, this.querySources(matchInputs[i])); + } + return matchingSources; + }; + // matchInput can either by a real event source object, an ID, or the function/URL for the source. + // returns an array of matching source objects. + EventManager.prototype.querySources = function (matchInput) { + var sources = this.otherSources; + var i; + var source; + // given a proper event source object + for (i = 0; i < sources.length; i++) { + source = sources[i]; + if (source === matchInput) { + return [source]; + } + } + // an ID match + source = this.getSourceById(EventSource_1.default.normalizeId(matchInput)); + if (source) { + return [source]; + } + // parse as an event source + matchInput = EventSourceParser_1.default.parse(matchInput, this.calendar); + if (matchInput) { + return $.grep(sources, function (source) { + return isSourcesEquivalent(matchInput, source); + }); + } + }; + /* + ID assumed to already be normalized + */ + EventManager.prototype.getSourceById = function (id) { + return $.grep(this.otherSources, function (source) { + return source.id && source.id === id; + })[0]; + }; + // Event-Period + // ----------------------------------------------------------------------------------------------------------------- + EventManager.prototype.setPeriod = function (eventPeriod) { + if (this.currentPeriod) { + this.unbindPeriod(this.currentPeriod); + this.currentPeriod = null; + } + this.currentPeriod = eventPeriod; + this.bindPeriod(eventPeriod); + eventPeriod.requestSources(this.getSources()); + }; + EventManager.prototype.bindPeriod = function (eventPeriod) { + this.listenTo(eventPeriod, 'release', function (eventsPayload) { + this.trigger('release', eventsPayload); + }); + }; + EventManager.prototype.unbindPeriod = function (eventPeriod) { + this.stopListeningTo(eventPeriod); + }; + // Event Getting/Adding/Removing + // ----------------------------------------------------------------------------------------------------------------- + EventManager.prototype.getEventDefByUid = function (uid) { + if (this.currentPeriod) { + return this.currentPeriod.getEventDefByUid(uid); + } + }; + EventManager.prototype.addEventDef = function (eventDef, isSticky) { + if (isSticky) { + this.stickySource.addEventDef(eventDef); + } + if (this.currentPeriod) { + this.currentPeriod.addEventDef(eventDef); // might release + } + }; + EventManager.prototype.removeEventDefsById = function (eventId) { + this.getSources().forEach(function (eventSource) { + eventSource.removeEventDefsById(eventId); + }); + if (this.currentPeriod) { + this.currentPeriod.removeEventDefsById(eventId); // might release + } + }; + EventManager.prototype.removeAllEventDefs = function () { + this.getSources().forEach(function (eventSource) { + eventSource.removeAllEventDefs(); + }); + if (this.currentPeriod) { + this.currentPeriod.removeAllEventDefs(); + } + }; + // Event Mutating + // ----------------------------------------------------------------------------------------------------------------- + /* + Returns an undo function. + */ + EventManager.prototype.mutateEventsWithId = function (eventDefId, eventDefMutation) { + var currentPeriod = this.currentPeriod; + var eventDefs; + var undoFuncs = []; + if (currentPeriod) { + currentPeriod.freeze(); + eventDefs = currentPeriod.getEventDefsById(eventDefId); + eventDefs.forEach(function (eventDef) { + // add/remove esp because id might change + currentPeriod.removeEventDef(eventDef); + undoFuncs.push(eventDefMutation.mutateSingle(eventDef)); + currentPeriod.addEventDef(eventDef); + }); + currentPeriod.thaw(); + return function () { + currentPeriod.freeze(); + for (var i = 0; i < eventDefs.length; i++) { + currentPeriod.removeEventDef(eventDefs[i]); + undoFuncs[i](); + currentPeriod.addEventDef(eventDefs[i]); + } + currentPeriod.thaw(); + }; + } + return function () { }; + }; + /* + copies and then mutates + */ + EventManager.prototype.buildMutatedEventInstanceGroup = function (eventDefId, eventDefMutation) { + var eventDefs = this.getEventDefsById(eventDefId); + var i; + var defCopy; + var allInstances = []; + for (i = 0; i < eventDefs.length; i++) { + defCopy = eventDefs[i].clone(); + if (defCopy instanceof SingleEventDef_1.default) { + eventDefMutation.mutateSingle(defCopy); + allInstances.push.apply(allInstances, // append + defCopy.buildInstances()); + } + } + return new EventInstanceGroup_1.default(allInstances); + }; + // Freezing + // ----------------------------------------------------------------------------------------------------------------- + EventManager.prototype.freeze = function () { + if (this.currentPeriod) { + this.currentPeriod.freeze(); + } + }; + EventManager.prototype.thaw = function () { + if (this.currentPeriod) { + this.currentPeriod.thaw(); + } + }; + // methods that simply forward to EventPeriod + EventManager.prototype.getEventDefsById = function (eventDefId) { + return this.currentPeriod.getEventDefsById(eventDefId); + }; + EventManager.prototype.getEventInstances = function () { + return this.currentPeriod.getEventInstances(); + }; + EventManager.prototype.getEventInstancesWithId = function (eventDefId) { + return this.currentPeriod.getEventInstancesWithId(eventDefId); + }; + EventManager.prototype.getEventInstancesWithoutId = function (eventDefId) { + return this.currentPeriod.getEventInstancesWithoutId(eventDefId); + }; + return EventManager; +}()); +exports.default = EventManager; +EmitterMixin_1.default.mixInto(EventManager); +ListenerMixin_1.default.mixInto(EventManager); +function isSourcesEquivalent(source0, source1) { + return source0.getPrimitive() === source1.getPrimitive(); +} + + +/***/ }), +/* 243 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var $ = __webpack_require__(3); +var util_1 = __webpack_require__(4); +var Promise_1 = __webpack_require__(20); +var EmitterMixin_1 = __webpack_require__(11); +var UnzonedRange_1 = __webpack_require__(5); +var EventInstanceGroup_1 = __webpack_require__(18); +var EventPeriod = /** @class */ (function () { + function EventPeriod(start, end, timezone) { + this.pendingCnt = 0; + this.freezeDepth = 0; + this.stuntedReleaseCnt = 0; + this.releaseCnt = 0; + this.start = start; + this.end = end; + this.timezone = timezone; + this.unzonedRange = new UnzonedRange_1.default(start.clone().stripZone(), end.clone().stripZone()); + this.requestsByUid = {}; + this.eventDefsByUid = {}; + this.eventDefsById = {}; + this.eventInstanceGroupsById = {}; + } + EventPeriod.prototype.isWithinRange = function (start, end) { + // TODO: use a range util function? + return !start.isBefore(this.start) && !end.isAfter(this.end); + }; + // Requesting and Purging + // ----------------------------------------------------------------------------------------------------------------- + EventPeriod.prototype.requestSources = function (sources) { + this.freeze(); + for (var i = 0; i < sources.length; i++) { + this.requestSource(sources[i]); + } + this.thaw(); + }; + EventPeriod.prototype.requestSource = function (source) { + var _this = this; + var request = { source: source, status: 'pending', eventDefs: null }; + this.requestsByUid[source.uid] = request; + this.pendingCnt += 1; + source.fetch(this.start, this.end, this.timezone).then(function (eventDefs) { + if (request.status !== 'cancelled') { + request.status = 'completed'; + request.eventDefs = eventDefs; + _this.addEventDefs(eventDefs); + _this.pendingCnt--; + _this.tryRelease(); + } + }, function () { + if (request.status !== 'cancelled') { + request.status = 'failed'; + _this.pendingCnt--; + _this.tryRelease(); + } + }); + }; + EventPeriod.prototype.purgeSource = function (source) { + var request = this.requestsByUid[source.uid]; + if (request) { + delete this.requestsByUid[source.uid]; + if (request.status === 'pending') { + request.status = 'cancelled'; + this.pendingCnt--; + this.tryRelease(); + } + else if (request.status === 'completed') { + request.eventDefs.forEach(this.removeEventDef.bind(this)); + } + } + }; + EventPeriod.prototype.purgeAllSources = function () { + var requestsByUid = this.requestsByUid; + var uid; + var request; + var completedCnt = 0; + for (uid in requestsByUid) { + request = requestsByUid[uid]; + if (request.status === 'pending') { + request.status = 'cancelled'; + } + else if (request.status === 'completed') { + completedCnt++; + } + } + this.requestsByUid = {}; + this.pendingCnt = 0; + if (completedCnt) { + this.removeAllEventDefs(); // might release + } + }; + // Event Definitions + // ----------------------------------------------------------------------------------------------------------------- + EventPeriod.prototype.getEventDefByUid = function (eventDefUid) { + return this.eventDefsByUid[eventDefUid]; + }; + EventPeriod.prototype.getEventDefsById = function (eventDefId) { + var a = this.eventDefsById[eventDefId]; + if (a) { + return a.slice(); // clone + } + return []; + }; + EventPeriod.prototype.addEventDefs = function (eventDefs) { + for (var i = 0; i < eventDefs.length; i++) { + this.addEventDef(eventDefs[i]); + } + }; + EventPeriod.prototype.addEventDef = function (eventDef) { + var eventDefsById = this.eventDefsById; + var eventDefId = eventDef.id; + var eventDefs = eventDefsById[eventDefId] || (eventDefsById[eventDefId] = []); + var eventInstances = eventDef.buildInstances(this.unzonedRange); + var i; + eventDefs.push(eventDef); + this.eventDefsByUid[eventDef.uid] = eventDef; + for (i = 0; i < eventInstances.length; i++) { + this.addEventInstance(eventInstances[i], eventDefId); + } + }; + EventPeriod.prototype.removeEventDefsById = function (eventDefId) { + var _this = this; + this.getEventDefsById(eventDefId).forEach(function (eventDef) { + _this.removeEventDef(eventDef); + }); + }; + EventPeriod.prototype.removeAllEventDefs = function () { + var isEmpty = $.isEmptyObject(this.eventDefsByUid); + this.eventDefsByUid = {}; + this.eventDefsById = {}; + this.eventInstanceGroupsById = {}; + if (!isEmpty) { + this.tryRelease(); + } + }; + EventPeriod.prototype.removeEventDef = function (eventDef) { + var eventDefsById = this.eventDefsById; + var eventDefs = eventDefsById[eventDef.id]; + delete this.eventDefsByUid[eventDef.uid]; + if (eventDefs) { + util_1.removeExact(eventDefs, eventDef); + if (!eventDefs.length) { + delete eventDefsById[eventDef.id]; + } + this.removeEventInstancesForDef(eventDef); + } + }; + // Event Instances + // ----------------------------------------------------------------------------------------------------------------- + EventPeriod.prototype.getEventInstances = function () { + var eventInstanceGroupsById = this.eventInstanceGroupsById; + var eventInstances = []; + var id; + for (id in eventInstanceGroupsById) { + eventInstances.push.apply(eventInstances, // append + eventInstanceGroupsById[id].eventInstances); + } + return eventInstances; + }; + EventPeriod.prototype.getEventInstancesWithId = function (eventDefId) { + var eventInstanceGroup = this.eventInstanceGroupsById[eventDefId]; + if (eventInstanceGroup) { + return eventInstanceGroup.eventInstances.slice(); // clone + } + return []; + }; + EventPeriod.prototype.getEventInstancesWithoutId = function (eventDefId) { + var eventInstanceGroupsById = this.eventInstanceGroupsById; + var matchingInstances = []; + var id; + for (id in eventInstanceGroupsById) { + if (id !== eventDefId) { + matchingInstances.push.apply(matchingInstances, // append + eventInstanceGroupsById[id].eventInstances); + } + } + return matchingInstances; + }; + EventPeriod.prototype.addEventInstance = function (eventInstance, eventDefId) { + var eventInstanceGroupsById = this.eventInstanceGroupsById; + var eventInstanceGroup = eventInstanceGroupsById[eventDefId] || + (eventInstanceGroupsById[eventDefId] = new EventInstanceGroup_1.default()); + eventInstanceGroup.eventInstances.push(eventInstance); + this.tryRelease(); + }; + EventPeriod.prototype.removeEventInstancesForDef = function (eventDef) { + var eventInstanceGroupsById = this.eventInstanceGroupsById; + var eventInstanceGroup = eventInstanceGroupsById[eventDef.id]; + var removeCnt; + if (eventInstanceGroup) { + removeCnt = util_1.removeMatching(eventInstanceGroup.eventInstances, function (currentEventInstance) { + return currentEventInstance.def === eventDef; + }); + if (!eventInstanceGroup.eventInstances.length) { + delete eventInstanceGroupsById[eventDef.id]; + } + if (removeCnt) { + this.tryRelease(); + } + } + }; + // Releasing and Freezing + // ----------------------------------------------------------------------------------------------------------------- + EventPeriod.prototype.tryRelease = function () { + if (!this.pendingCnt) { + if (!this.freezeDepth) { + this.release(); + } + else { + this.stuntedReleaseCnt++; + } + } + }; + EventPeriod.prototype.release = function () { + this.releaseCnt++; + this.trigger('release', this.eventInstanceGroupsById); + }; + EventPeriod.prototype.whenReleased = function () { + var _this = this; + if (this.releaseCnt) { + return Promise_1.default.resolve(this.eventInstanceGroupsById); + } + else { + return Promise_1.default.construct(function (onResolve) { + _this.one('release', onResolve); + }); + } + }; + EventPeriod.prototype.freeze = function () { + if (!(this.freezeDepth++)) { + this.stuntedReleaseCnt = 0; + } + }; + EventPeriod.prototype.thaw = function () { + if (!(--this.freezeDepth) && this.stuntedReleaseCnt && !this.pendingCnt) { + this.release(); + } + }; + return EventPeriod; +}()); +exports.default = EventPeriod; +EmitterMixin_1.default.mixInto(EventPeriod); + + +/***/ }), +/* 244 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var $ = __webpack_require__(3); +var util_1 = __webpack_require__(4); +var ListenerMixin_1 = __webpack_require__(7); +/* Creates a clone of an element and lets it track the mouse as it moves +----------------------------------------------------------------------------------------------------------------------*/ +var MouseFollower = /** @class */ (function () { + function MouseFollower(sourceEl, options) { + this.isFollowing = false; + this.isHidden = false; + this.isAnimating = false; // doing the revert animation? + this.options = options = options || {}; + this.sourceEl = sourceEl; + this.parentEl = options.parentEl ? $(options.parentEl) : sourceEl.parent(); // default to sourceEl's parent + } + // Causes the element to start following the mouse + MouseFollower.prototype.start = function (ev) { + if (!this.isFollowing) { + this.isFollowing = true; + this.y0 = util_1.getEvY(ev); + this.x0 = util_1.getEvX(ev); + this.topDelta = 0; + this.leftDelta = 0; + if (!this.isHidden) { + this.updatePosition(); + } + if (util_1.getEvIsTouch(ev)) { + this.listenTo($(document), 'touchmove', this.handleMove); + } + else { + this.listenTo($(document), 'mousemove', this.handleMove); + } + } + }; + // Causes the element to stop following the mouse. If shouldRevert is true, will animate back to original position. + // `callback` gets invoked when the animation is complete. If no animation, it is invoked immediately. + MouseFollower.prototype.stop = function (shouldRevert, callback) { + var _this = this; + var revertDuration = this.options.revertDuration; + var complete = function () { + _this.isAnimating = false; + _this.removeElement(); + _this.top0 = _this.left0 = null; // reset state for future updatePosition calls + if (callback) { + callback(); + } + }; + if (this.isFollowing && !this.isAnimating) { + this.isFollowing = false; + this.stopListeningTo($(document)); + if (shouldRevert && revertDuration && !this.isHidden) { + this.isAnimating = true; + this.el.animate({ + top: this.top0, + left: this.left0 + }, { + duration: revertDuration, + complete: complete + }); + } + else { + complete(); + } + } + }; + // Gets the tracking element. Create it if necessary + MouseFollower.prototype.getEl = function () { + var el = this.el; + if (!el) { + el = this.el = this.sourceEl.clone() + .addClass(this.options.additionalClass || '') + .css({ + position: 'absolute', + visibility: '', + display: this.isHidden ? 'none' : '', + margin: 0, + right: 'auto', + bottom: 'auto', + width: this.sourceEl.width(), + height: this.sourceEl.height(), + opacity: this.options.opacity || '', + zIndex: this.options.zIndex + }); + // we don't want long taps or any mouse interaction causing selection/menus. + // would use preventSelection(), but that prevents selectstart, causing problems. + el.addClass('fc-unselectable'); + el.appendTo(this.parentEl); + } + return el; + }; + // Removes the tracking element if it has already been created + MouseFollower.prototype.removeElement = function () { + if (this.el) { + this.el.remove(); + this.el = null; + } + }; + // Update the CSS position of the tracking element + MouseFollower.prototype.updatePosition = function () { + var sourceOffset; + var origin; + this.getEl(); // ensure this.el + // make sure origin info was computed + if (this.top0 == null) { + sourceOffset = this.sourceEl.offset(); + origin = this.el.offsetParent().offset(); + this.top0 = sourceOffset.top - origin.top; + this.left0 = sourceOffset.left - origin.left; + } + this.el.css({ + top: this.top0 + this.topDelta, + left: this.left0 + this.leftDelta + }); + }; + // Gets called when the user moves the mouse + MouseFollower.prototype.handleMove = function (ev) { + this.topDelta = util_1.getEvY(ev) - this.y0; + this.leftDelta = util_1.getEvX(ev) - this.x0; + if (!this.isHidden) { + this.updatePosition(); + } + }; + // Temporarily makes the tracking element invisible. Can be called before following starts + MouseFollower.prototype.hide = function () { + if (!this.isHidden) { + this.isHidden = true; + if (this.el) { + this.el.hide(); + } + } + }; + // Show the tracking element after it has been temporarily hidden + MouseFollower.prototype.show = function () { + if (this.isHidden) { + this.isHidden = false; + this.updatePosition(); + this.getEl().show(); + } + }; + return MouseFollower; +}()); +exports.default = MouseFollower; +ListenerMixin_1.default.mixInto(MouseFollower); + + +/***/ }), +/* 245 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = __webpack_require__(2); +var HitDragListener_1 = __webpack_require__(23); +var Interaction_1 = __webpack_require__(15); +var DateClicking = /** @class */ (function (_super) { + tslib_1.__extends(DateClicking, _super); + /* + component must implement: + - bindDateHandlerToEl + - getSafeHitFootprint + - getHitEl + */ + function DateClicking(component) { + var _this = _super.call(this, component) || this; + _this.dragListener = _this.buildDragListener(); + return _this; + } + DateClicking.prototype.end = function () { + this.dragListener.endInteraction(); + }; + DateClicking.prototype.bindToEl = function (el) { + var component = this.component; + var dragListener = this.dragListener; + component.bindDateHandlerToEl(el, 'mousedown', function (ev) { + if (!component.shouldIgnoreMouse()) { + dragListener.startInteraction(ev); + } + }); + component.bindDateHandlerToEl(el, 'touchstart', function (ev) { + if (!component.shouldIgnoreTouch()) { + dragListener.startInteraction(ev); + } + }); + }; + // Creates a listener that tracks the user's drag across day elements, for day clicking. + DateClicking.prototype.buildDragListener = function () { + var _this = this; + var component = this.component; + var dayClickHit; // null if invalid dayClick + var dragListener = new HitDragListener_1.default(component, { + scroll: this.opt('dragScroll'), + interactionStart: function () { + dayClickHit = dragListener.origHit; + }, + hitOver: function (hit, isOrig, origHit) { + // if user dragged to another cell at any point, it can no longer be a dayClick + if (!isOrig) { + dayClickHit = null; + } + }, + hitOut: function () { + dayClickHit = null; + }, + interactionEnd: function (ev, isCancelled) { + var componentFootprint; + if (!isCancelled && dayClickHit) { + componentFootprint = component.getSafeHitFootprint(dayClickHit); + if (componentFootprint) { + _this.view.triggerDayClick(componentFootprint, component.getHitEl(dayClickHit), ev); + } + } + } + }); + // because dragListener won't be called with any time delay, "dragging" will begin immediately, + // which will kill any touchmoving/scrolling. Prevent this. + dragListener.shouldCancelTouchScroll = false; + dragListener.scrollAlwaysKills = true; + return dragListener; + }; + return DateClicking; +}(Interaction_1.default)); +exports.default = DateClicking; + + +/***/ }), +/* 246 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = __webpack_require__(2); +var util_1 = __webpack_require__(4); +var EventRenderer_1 = __webpack_require__(42); +/* +Only handles foreground segs. +Does not own rendering. Use for low-level util methods by TimeGrid. +*/ +var TimeGridEventRenderer = /** @class */ (function (_super) { + tslib_1.__extends(TimeGridEventRenderer, _super); + function TimeGridEventRenderer(timeGrid, fillRenderer) { + var _this = _super.call(this, timeGrid, fillRenderer) || this; + _this.timeGrid = timeGrid; + return _this; + } + TimeGridEventRenderer.prototype.renderFgSegs = function (segs) { + this.renderFgSegsIntoContainers(segs, this.timeGrid.fgContainerEls); + }; + // Given an array of foreground segments, render a DOM element for each, computes position, + // and attaches to the column inner-container elements. + TimeGridEventRenderer.prototype.renderFgSegsIntoContainers = function (segs, containerEls) { + var segsByCol; + var col; + segsByCol = this.timeGrid.groupSegsByCol(segs); + for (col = 0; col < this.timeGrid.colCnt; col++) { + this.updateFgSegCoords(segsByCol[col]); + } + this.timeGrid.attachSegsByCol(segsByCol, containerEls); + }; + TimeGridEventRenderer.prototype.unrenderFgSegs = function () { + if (this.fgSegs) { + this.fgSegs.forEach(function (seg) { + seg.el.remove(); + }); + } + }; + // Computes a default event time formatting string if `timeFormat` is not explicitly defined + TimeGridEventRenderer.prototype.computeEventTimeFormat = function () { + return this.opt('noMeridiemTimeFormat'); // like "6:30" (no AM/PM) + }; + // Computes a default `displayEventEnd` value if one is not expliclty defined + TimeGridEventRenderer.prototype.computeDisplayEventEnd = function () { + return true; + }; + // Renders the HTML for a single event segment's default rendering + TimeGridEventRenderer.prototype.fgSegHtml = function (seg, disableResizing) { + var view = this.view; + var calendar = view.calendar; + var componentFootprint = seg.footprint.componentFootprint; + var isAllDay = componentFootprint.isAllDay; + var eventDef = seg.footprint.eventDef; + var isDraggable = view.isEventDefDraggable(eventDef); + var isResizableFromStart = !disableResizing && seg.isStart && view.isEventDefResizableFromStart(eventDef); + var isResizableFromEnd = !disableResizing && seg.isEnd && view.isEventDefResizableFromEnd(eventDef); + var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd); + var skinCss = util_1.cssToStr(this.getSkinCss(eventDef)); + var timeText; + var fullTimeText; // more verbose time text. for the print stylesheet + var startTimeText; // just the start time text + classes.unshift('fc-time-grid-event', 'fc-v-event'); + // if the event appears to span more than one day... + if (view.isMultiDayRange(componentFootprint.unzonedRange)) { + // Don't display time text on segments that run entirely through a day. + // That would appear as midnight-midnight and would look dumb. + // Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am) + if (seg.isStart || seg.isEnd) { + var zonedStart = calendar.msToMoment(seg.startMs); + var zonedEnd = calendar.msToMoment(seg.endMs); + timeText = this._getTimeText(zonedStart, zonedEnd, isAllDay); + fullTimeText = this._getTimeText(zonedStart, zonedEnd, isAllDay, 'LT'); + startTimeText = this._getTimeText(zonedStart, zonedEnd, isAllDay, null, false); // displayEnd=false + } + } + else { + // Display the normal time text for the *event's* times + timeText = this.getTimeText(seg.footprint); + fullTimeText = this.getTimeText(seg.footprint, 'LT'); + startTimeText = this.getTimeText(seg.footprint, null, false); // displayEnd=false + } + return '' + + '
    ' + + (timeText ? + '
    ' + + '' + util_1.htmlEscape(timeText) + '' + + '
    ' : + '') + + (eventDef.title ? + '
    ' + + util_1.htmlEscape(eventDef.title) + + '
    ' : + '') + + '
    ' + + '
    ' + + /* TODO: write CSS for this + (isResizableFromStart ? + '
    ' : + '' + ) + + */ + (isResizableFromEnd ? + '
    ' : + '') + + ''; + }; + // Given segments that are assumed to all live in the *same column*, + // compute their verical/horizontal coordinates and assign to their elements. + TimeGridEventRenderer.prototype.updateFgSegCoords = function (segs) { + this.timeGrid.computeSegVerticals(segs); // horizontals relies on this + this.computeFgSegHorizontals(segs); // compute horizontal coordinates, z-index's, and reorder the array + this.timeGrid.assignSegVerticals(segs); + this.assignFgSegHorizontals(segs); + }; + // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each. + // NOTE: Also reorders the given array by date! + TimeGridEventRenderer.prototype.computeFgSegHorizontals = function (segs) { + var levels; + var level0; + var i; + this.sortEventSegs(segs); // order by certain criteria + levels = buildSlotSegLevels(segs); + computeForwardSlotSegs(levels); + if ((level0 = levels[0])) { + for (i = 0; i < level0.length; i++) { + computeSlotSegPressures(level0[i]); + } + for (i = 0; i < level0.length; i++) { + this.computeFgSegForwardBack(level0[i], 0, 0); + } + } + }; + // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range + // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and + // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left. + // + // The segment might be part of a "series", which means consecutive segments with the same pressure + // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of + // segments behind this one in the current series, and `seriesBackwardCoord` is the starting + // coordinate of the first segment in the series. + TimeGridEventRenderer.prototype.computeFgSegForwardBack = function (seg, seriesBackwardPressure, seriesBackwardCoord) { + var forwardSegs = seg.forwardSegs; + var i; + if (seg.forwardCoord === undefined) { + if (!forwardSegs.length) { + // if there are no forward segments, this segment should butt up against the edge + seg.forwardCoord = 1; + } + else { + // sort highest pressure first + this.sortForwardSegs(forwardSegs); + // this segment's forwardCoord will be calculated from the backwardCoord of the + // highest-pressure forward segment. + this.computeFgSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord); + seg.forwardCoord = forwardSegs[0].backwardCoord; + } + // calculate the backwardCoord from the forwardCoord. consider the series + seg.backwardCoord = seg.forwardCoord - + (seg.forwardCoord - seriesBackwardCoord) / // available width for series + (seriesBackwardPressure + 1); // # of segments in the series + // use this segment's coordinates to computed the coordinates of the less-pressurized + // forward segments + for (i = 0; i < forwardSegs.length; i++) { + this.computeFgSegForwardBack(forwardSegs[i], 0, seg.forwardCoord); + } + } + }; + TimeGridEventRenderer.prototype.sortForwardSegs = function (forwardSegs) { + forwardSegs.sort(util_1.proxy(this, 'compareForwardSegs')); + }; + // A cmp function for determining which forward segment to rely on more when computing coordinates. + TimeGridEventRenderer.prototype.compareForwardSegs = function (seg1, seg2) { + // put higher-pressure first + return seg2.forwardPressure - seg1.forwardPressure || + // put segments that are closer to initial edge first (and favor ones with no coords yet) + (seg1.backwardCoord || 0) - (seg2.backwardCoord || 0) || + // do normal sorting... + this.compareEventSegs(seg1, seg2); + }; + // Given foreground event segments that have already had their position coordinates computed, + // assigns position-related CSS values to their elements. + TimeGridEventRenderer.prototype.assignFgSegHorizontals = function (segs) { + var i; + var seg; + for (i = 0; i < segs.length; i++) { + seg = segs[i]; + seg.el.css(this.generateFgSegHorizontalCss(seg)); + // if the height is short, add a className for alternate styling + if (seg.bottom - seg.top < 30) { + seg.el.addClass('fc-short'); + } + } + }; + // Generates an object with CSS properties/values that should be applied to an event segment element. + // Contains important positioning-related properties that should be applied to any event element, customized or not. + TimeGridEventRenderer.prototype.generateFgSegHorizontalCss = function (seg) { + var shouldOverlap = this.opt('slotEventOverlap'); + var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point + var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point + var props = this.timeGrid.generateSegVerticalCss(seg); // get top/bottom first + var isRTL = this.timeGrid.isRTL; + var left; // amount of space from left edge, a fraction of the total width + var right; // amount of space from right edge, a fraction of the total width + if (shouldOverlap) { + // double the width, but don't go beyond the maximum forward coordinate (1.0) + forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2); + } + if (isRTL) { + left = 1 - forwardCoord; + right = backwardCoord; + } + else { + left = backwardCoord; + right = 1 - forwardCoord; + } + props.zIndex = seg.level + 1; // convert from 0-base to 1-based + props.left = left * 100 + '%'; + props.right = right * 100 + '%'; + if (shouldOverlap && seg.forwardPressure) { + // add padding to the edge so that forward stacked events don't cover the resizer's icon + props[isRTL ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width + } + return props; + }; + return TimeGridEventRenderer; +}(EventRenderer_1.default)); +exports.default = TimeGridEventRenderer; +// Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is +// left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date. +function buildSlotSegLevels(segs) { + var levels = []; + var i; + var seg; + var j; + for (i = 0; i < segs.length; i++) { + seg = segs[i]; + // go through all the levels and stop on the first level where there are no collisions + for (j = 0; j < levels.length; j++) { + if (!computeSlotSegCollisions(seg, levels[j]).length) { + break; + } + } + seg.level = j; + (levels[j] || (levels[j] = [])).push(seg); + } + return levels; +} +// For every segment, figure out the other segments that are in subsequent +// levels that also occupy the same vertical space. Accumulate in seg.forwardSegs +function computeForwardSlotSegs(levels) { + var i; + var level; + var j; + var seg; + var k; + for (i = 0; i < levels.length; i++) { + level = levels[i]; + for (j = 0; j < level.length; j++) { + seg = level[j]; + seg.forwardSegs = []; + for (k = i + 1; k < levels.length; k++) { + computeSlotSegCollisions(seg, levels[k], seg.forwardSegs); + } + } + } +} +// Figure out which path forward (via seg.forwardSegs) results in the longest path until +// the furthest edge is reached. The number of segments in this path will be seg.forwardPressure +function computeSlotSegPressures(seg) { + var forwardSegs = seg.forwardSegs; + var forwardPressure = 0; + var i; + var forwardSeg; + if (seg.forwardPressure === undefined) { + for (i = 0; i < forwardSegs.length; i++) { + forwardSeg = forwardSegs[i]; + // figure out the child's maximum forward path + computeSlotSegPressures(forwardSeg); + // either use the existing maximum, or use the child's forward pressure + // plus one (for the forwardSeg itself) + forwardPressure = Math.max(forwardPressure, 1 + forwardSeg.forwardPressure); + } + seg.forwardPressure = forwardPressure; + } +} +// Find all the segments in `otherSegs` that vertically collide with `seg`. +// Append into an optionally-supplied `results` array and return. +function computeSlotSegCollisions(seg, otherSegs, results) { + if (results === void 0) { results = []; } + for (var i = 0; i < otherSegs.length; i++) { + if (isSlotSegCollision(seg, otherSegs[i])) { + results.push(otherSegs[i]); + } + } + return results; +} +// Do these segments occupy the same vertical space? +function isSlotSegCollision(seg1, seg2) { + return seg1.bottom > seg2.top && seg1.top < seg2.bottom; +} + + +/***/ }), +/* 247 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = __webpack_require__(2); +var $ = __webpack_require__(3); +var HelperRenderer_1 = __webpack_require__(58); +var TimeGridHelperRenderer = /** @class */ (function (_super) { + tslib_1.__extends(TimeGridHelperRenderer, _super); + function TimeGridHelperRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + TimeGridHelperRenderer.prototype.renderSegs = function (segs, sourceSeg) { + var helperNodes = []; + var i; + var seg; + var sourceEl; + // TODO: not good to call eventRenderer this way + this.eventRenderer.renderFgSegsIntoContainers(segs, this.component.helperContainerEls); + // Try to make the segment that is in the same row as sourceSeg look the same + for (i = 0; i < segs.length; i++) { + seg = segs[i]; + if (sourceSeg && sourceSeg.col === seg.col) { + sourceEl = sourceSeg.el; + seg.el.css({ + left: sourceEl.css('left'), + right: sourceEl.css('right'), + 'margin-left': sourceEl.css('margin-left'), + 'margin-right': sourceEl.css('margin-right') + }); + } + helperNodes.push(seg.el[0]); + } + return $(helperNodes); // must return the elements rendered + }; + return TimeGridHelperRenderer; +}(HelperRenderer_1.default)); +exports.default = TimeGridHelperRenderer; + + +/***/ }), +/* 248 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = __webpack_require__(2); +var FillRenderer_1 = __webpack_require__(57); +var TimeGridFillRenderer = /** @class */ (function (_super) { + tslib_1.__extends(TimeGridFillRenderer, _super); + function TimeGridFillRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + TimeGridFillRenderer.prototype.attachSegEls = function (type, segs) { + var timeGrid = this.component; + var containerEls; + // TODO: more efficient lookup + if (type === 'bgEvent') { + containerEls = timeGrid.bgContainerEls; + } + else if (type === 'businessHours') { + containerEls = timeGrid.businessContainerEls; + } + else if (type === 'highlight') { + containerEls = timeGrid.highlightContainerEls; + } + timeGrid.updateSegVerticals(segs); + timeGrid.attachSegsByCol(timeGrid.groupSegsByCol(segs), containerEls); + return segs.map(function (seg) { + return seg.el[0]; + }); + }; + return TimeGridFillRenderer; +}(FillRenderer_1.default)); +exports.default = TimeGridFillRenderer; + + +/***/ }), +/* 249 */ +/***/ (function(module, exports, __webpack_require__) { + +/* A rectangular panel that is absolutely positioned over other content +------------------------------------------------------------------------------------------------------------------------ +Options: + - className (string) + - content (HTML string or jQuery element set) + - parentEl + - top + - left + - right (the x coord of where the right edge should be. not a "CSS" right) + - autoHide (boolean) + - show (callback) + - hide (callback) +*/ +Object.defineProperty(exports, "__esModule", { value: true }); +var $ = __webpack_require__(3); +var util_1 = __webpack_require__(4); +var ListenerMixin_1 = __webpack_require__(7); +var Popover = /** @class */ (function () { + function Popover(options) { + this.isHidden = true; + this.margin = 10; // the space required between the popover and the edges of the scroll container + this.options = options || {}; + } + // Shows the popover on the specified position. Renders it if not already + Popover.prototype.show = function () { + if (this.isHidden) { + if (!this.el) { + this.render(); + } + this.el.show(); + this.position(); + this.isHidden = false; + this.trigger('show'); + } + }; + // Hides the popover, through CSS, but does not remove it from the DOM + Popover.prototype.hide = function () { + if (!this.isHidden) { + this.el.hide(); + this.isHidden = true; + this.trigger('hide'); + } + }; + // Creates `this.el` and renders content inside of it + Popover.prototype.render = function () { + var _this = this; + var options = this.options; + this.el = $('
    ') + .addClass(options.className || '') + .css({ + // position initially to the top left to avoid creating scrollbars + top: 0, + left: 0 + }) + .append(options.content) + .appendTo(options.parentEl); + // when a click happens on anything inside with a 'fc-close' className, hide the popover + this.el.on('click', '.fc-close', function () { + _this.hide(); + }); + if (options.autoHide) { + this.listenTo($(document), 'mousedown', this.documentMousedown); + } + }; + // Triggered when the user clicks *anywhere* in the document, for the autoHide feature + Popover.prototype.documentMousedown = function (ev) { + // only hide the popover if the click happened outside the popover + if (this.el && !$(ev.target).closest(this.el).length) { + this.hide(); + } + }; + // Hides and unregisters any handlers + Popover.prototype.removeElement = function () { + this.hide(); + if (this.el) { + this.el.remove(); + this.el = null; + } + this.stopListeningTo($(document), 'mousedown'); + }; + // Positions the popover optimally, using the top/left/right options + Popover.prototype.position = function () { + var options = this.options; + var origin = this.el.offsetParent().offset(); + var width = this.el.outerWidth(); + var height = this.el.outerHeight(); + var windowEl = $(window); + var viewportEl = util_1.getScrollParent(this.el); + var viewportTop; + var viewportLeft; + var viewportOffset; + var top; // the "position" (not "offset") values for the popover + var left; // + // compute top and left + top = options.top || 0; + if (options.left !== undefined) { + left = options.left; + } + else if (options.right !== undefined) { + left = options.right - width; // derive the left value from the right value + } + else { + left = 0; + } + if (viewportEl.is(window) || viewportEl.is(document)) { + viewportEl = windowEl; + viewportTop = 0; // the window is always at the top left + viewportLeft = 0; // (and .offset() won't work if called here) + } + else { + viewportOffset = viewportEl.offset(); + viewportTop = viewportOffset.top; + viewportLeft = viewportOffset.left; + } + // if the window is scrolled, it causes the visible area to be further down + viewportTop += windowEl.scrollTop(); + viewportLeft += windowEl.scrollLeft(); + // constrain to the view port. if constrained by two edges, give precedence to top/left + if (options.viewportConstrain !== false) { + top = Math.min(top, viewportTop + viewportEl.outerHeight() - height - this.margin); + top = Math.max(top, viewportTop + this.margin); + left = Math.min(left, viewportLeft + viewportEl.outerWidth() - width - this.margin); + left = Math.max(left, viewportLeft + this.margin); + } + this.el.css({ + top: top - origin.top, + left: left - origin.left + }); + }; + // Triggers a callback. Calls a function in the option hash of the same name. + // Arguments beyond the first `name` are forwarded on. + // TODO: better code reuse for this. Repeat code + Popover.prototype.trigger = function (name) { + if (this.options[name]) { + this.options[name].apply(this, Array.prototype.slice.call(arguments, 1)); + } + }; + return Popover; +}()); +exports.default = Popover; +ListenerMixin_1.default.mixInto(Popover); + + +/***/ }), +/* 250 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = __webpack_require__(2); +var $ = __webpack_require__(3); +var util_1 = __webpack_require__(4); +var EventRenderer_1 = __webpack_require__(42); +/* Event-rendering methods for the DayGrid class +----------------------------------------------------------------------------------------------------------------------*/ +var DayGridEventRenderer = /** @class */ (function (_super) { + tslib_1.__extends(DayGridEventRenderer, _super); + function DayGridEventRenderer(dayGrid, fillRenderer) { + var _this = _super.call(this, dayGrid, fillRenderer) || this; + _this.dayGrid = dayGrid; + return _this; + } + DayGridEventRenderer.prototype.renderBgRanges = function (eventRanges) { + // don't render timed background events + eventRanges = $.grep(eventRanges, function (eventRange) { + return eventRange.eventDef.isAllDay(); + }); + _super.prototype.renderBgRanges.call(this, eventRanges); + }; + // Renders the given foreground event segments onto the grid + DayGridEventRenderer.prototype.renderFgSegs = function (segs) { + var rowStructs = this.rowStructs = this.renderSegRows(segs); + // append to each row's content skeleton + this.dayGrid.rowEls.each(function (i, rowNode) { + $(rowNode).find('.fc-content-skeleton > table').append(rowStructs[i].tbodyEl); + }); + }; + // Unrenders all currently rendered foreground event segments + DayGridEventRenderer.prototype.unrenderFgSegs = function () { + var rowStructs = this.rowStructs || []; + var rowStruct; + while ((rowStruct = rowStructs.pop())) { + rowStruct.tbodyEl.remove(); + } + this.rowStructs = null; + }; + // Uses the given events array to generate elements that should be appended to each row's content skeleton. + // Returns an array of rowStruct objects (see the bottom of `renderSegRow`). + // PRECONDITION: each segment shoud already have a rendered and assigned `.el` + DayGridEventRenderer.prototype.renderSegRows = function (segs) { + var rowStructs = []; + var segRows; + var row; + segRows = this.groupSegRows(segs); // group into nested arrays + // iterate each row of segment groupings + for (row = 0; row < segRows.length; row++) { + rowStructs.push(this.renderSegRow(row, segRows[row])); + } + return rowStructs; + }; + // Given a row # and an array of segments all in the same row, render a element, a skeleton that contains + // the segments. Returns object with a bunch of internal data about how the render was calculated. + // NOTE: modifies rowSegs + DayGridEventRenderer.prototype.renderSegRow = function (row, rowSegs) { + var colCnt = this.dayGrid.colCnt; + var segLevels = this.buildSegLevels(rowSegs); // group into sub-arrays of levels + var levelCnt = Math.max(1, segLevels.length); // ensure at least one level + var tbody = $(''); + var segMatrix = []; // lookup for which segments are rendered into which level+col cells + var cellMatrix = []; // lookup for all elements of the level+col matrix + var loneCellMatrix = []; // lookup for elements that only take up a single column + var i; + var levelSegs; + var col; + var tr; + var j; + var seg; + var td; + // populates empty cells from the current column (`col`) to `endCol` + function emptyCellsUntil(endCol) { + while (col < endCol) { + // try to grab a cell from the level above and extend its rowspan. otherwise, create a fresh cell + td = (loneCellMatrix[i - 1] || [])[col]; + if (td) { + td.attr('rowspan', parseInt(td.attr('rowspan') || 1, 10) + 1); + } + else { + td = $(''); + tr.append(td); + } + cellMatrix[i][col] = td; + loneCellMatrix[i][col] = td; + col++; + } + } + for (i = 0; i < levelCnt; i++) { + levelSegs = segLevels[i]; + col = 0; + tr = $(''); + segMatrix.push([]); + cellMatrix.push([]); + loneCellMatrix.push([]); + // levelCnt might be 1 even though there are no actual levels. protect against this. + // this single empty row is useful for styling. + if (levelSegs) { + for (j = 0; j < levelSegs.length; j++) { + seg = levelSegs[j]; + emptyCellsUntil(seg.leftCol); + // create a container that occupies or more columns. append the event element. + td = $('').append(seg.el); + if (seg.leftCol !== seg.rightCol) { + td.attr('colspan', seg.rightCol - seg.leftCol + 1); + } + else { + loneCellMatrix[i][col] = td; + } + while (col <= seg.rightCol) { + cellMatrix[i][col] = td; + segMatrix[i][col] = seg; + col++; + } + tr.append(td); + } + } + emptyCellsUntil(colCnt); // finish off the row + this.dayGrid.bookendCells(tr); + tbody.append(tr); + } + return { + row: row, + tbodyEl: tbody, + cellMatrix: cellMatrix, + segMatrix: segMatrix, + segLevels: segLevels, + segs: rowSegs + }; + }; + // Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels. + // NOTE: modifies segs + DayGridEventRenderer.prototype.buildSegLevels = function (segs) { + var levels = []; + var i; + var seg; + var j; + // Give preference to elements with certain criteria, so they have + // a chance to be closer to the top. + this.sortEventSegs(segs); + for (i = 0; i < segs.length; i++) { + seg = segs[i]; + // loop through levels, starting with the topmost, until the segment doesn't collide with other segments + for (j = 0; j < levels.length; j++) { + if (!isDaySegCollision(seg, levels[j])) { + break; + } + } + // `j` now holds the desired subrow index + seg.level = j; + // create new level array if needed and append segment + (levels[j] || (levels[j] = [])).push(seg); + } + // order segments left-to-right. very important if calendar is RTL + for (j = 0; j < levels.length; j++) { + levels[j].sort(compareDaySegCols); + } + return levels; + }; + // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row + DayGridEventRenderer.prototype.groupSegRows = function (segs) { + var segRows = []; + var i; + for (i = 0; i < this.dayGrid.rowCnt; i++) { + segRows.push([]); + } + for (i = 0; i < segs.length; i++) { + segRows[segs[i].row].push(segs[i]); + } + return segRows; + }; + // Computes a default event time formatting string if `timeFormat` is not explicitly defined + DayGridEventRenderer.prototype.computeEventTimeFormat = function () { + return this.opt('extraSmallTimeFormat'); // like "6p" or "6:30p" + }; + // Computes a default `displayEventEnd` value if one is not expliclty defined + DayGridEventRenderer.prototype.computeDisplayEventEnd = function () { + return this.dayGrid.colCnt === 1; // we'll likely have space if there's only one day + }; + // Builds the HTML to be used for the default element for an individual segment + DayGridEventRenderer.prototype.fgSegHtml = function (seg, disableResizing) { + var view = this.view; + var eventDef = seg.footprint.eventDef; + var isAllDay = seg.footprint.componentFootprint.isAllDay; + var isDraggable = view.isEventDefDraggable(eventDef); + var isResizableFromStart = !disableResizing && isAllDay && + seg.isStart && view.isEventDefResizableFromStart(eventDef); + var isResizableFromEnd = !disableResizing && isAllDay && + seg.isEnd && view.isEventDefResizableFromEnd(eventDef); + var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd); + var skinCss = util_1.cssToStr(this.getSkinCss(eventDef)); + var timeHtml = ''; + var timeText; + var titleHtml; + classes.unshift('fc-day-grid-event', 'fc-h-event'); + // Only display a timed events time if it is the starting segment + if (seg.isStart) { + timeText = this.getTimeText(seg.footprint); + if (timeText) { + timeHtml = '' + util_1.htmlEscape(timeText) + ''; + } + } + titleHtml = + '' + + (util_1.htmlEscape(eventDef.title || '') || ' ') + // we always want one line of height + ''; + return '' + + '
    ' + + (this.dayGrid.isRTL ? + titleHtml + ' ' + timeHtml : // put a natural space in between + timeHtml + ' ' + titleHtml // + ) + + '
    ' + + (isResizableFromStart ? + '
    ' : + '') + + (isResizableFromEnd ? + '
    ' : + '') + + ''; + }; + return DayGridEventRenderer; +}(EventRenderer_1.default)); +exports.default = DayGridEventRenderer; +// Computes whether two segments' columns collide. They are assumed to be in the same row. +function isDaySegCollision(seg, otherSegs) { + var i; + var otherSeg; + for (i = 0; i < otherSegs.length; i++) { + otherSeg = otherSegs[i]; + if (otherSeg.leftCol <= seg.rightCol && + otherSeg.rightCol >= seg.leftCol) { + return true; + } + } + return false; +} +// A cmp function for determining the leftmost event +function compareDaySegCols(a, b) { + return a.leftCol - b.leftCol; +} + + +/***/ }), +/* 251 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = __webpack_require__(2); +var $ = __webpack_require__(3); +var HelperRenderer_1 = __webpack_require__(58); +var DayGridHelperRenderer = /** @class */ (function (_super) { + tslib_1.__extends(DayGridHelperRenderer, _super); + function DayGridHelperRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + // Renders a mock "helper" event. `sourceSeg` is the associated internal segment object. It can be null. + DayGridHelperRenderer.prototype.renderSegs = function (segs, sourceSeg) { + var helperNodes = []; + var rowStructs; + // TODO: not good to call eventRenderer this way + rowStructs = this.eventRenderer.renderSegRows(segs); + // inject each new event skeleton into each associated row + this.component.rowEls.each(function (row, rowNode) { + var rowEl = $(rowNode); // the .fc-row + var skeletonEl = $('
    '); // will be absolutely positioned + var skeletonTopEl; + var skeletonTop; + // If there is an original segment, match the top position. Otherwise, put it at the row's top level + if (sourceSeg && sourceSeg.row === row) { + skeletonTop = sourceSeg.el.position().top; + } + else { + skeletonTopEl = rowEl.find('.fc-content-skeleton tbody'); + if (!skeletonTopEl.length) { + skeletonTopEl = rowEl.find('.fc-content-skeleton table'); + } + skeletonTop = skeletonTopEl.position().top; + } + skeletonEl.css('top', skeletonTop) + .find('table') + .append(rowStructs[row].tbodyEl); + rowEl.append(skeletonEl); + helperNodes.push(skeletonEl[0]); + }); + return $(helperNodes); // must return the elements rendered + }; + return DayGridHelperRenderer; +}(HelperRenderer_1.default)); +exports.default = DayGridHelperRenderer; + + +/***/ }), +/* 252 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = __webpack_require__(2); +var $ = __webpack_require__(3); +var FillRenderer_1 = __webpack_require__(57); +var DayGridFillRenderer = /** @class */ (function (_super) { + tslib_1.__extends(DayGridFillRenderer, _super); + function DayGridFillRenderer() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.fillSegTag = 'td'; // override the default tag name + return _this; + } + DayGridFillRenderer.prototype.attachSegEls = function (type, segs) { + var nodes = []; + var i; + var seg; + var skeletonEl; + for (i = 0; i < segs.length; i++) { + seg = segs[i]; + skeletonEl = this.renderFillRow(type, seg); + this.component.rowEls.eq(seg.row).append(skeletonEl); + nodes.push(skeletonEl[0]); + } + return nodes; + }; + // Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered. + DayGridFillRenderer.prototype.renderFillRow = function (type, seg) { + var colCnt = this.component.colCnt; + var startCol = seg.leftCol; + var endCol = seg.rightCol + 1; + var className; + var skeletonEl; + var trEl; + if (type === 'businessHours') { + className = 'bgevent'; + } + else { + className = type.toLowerCase(); + } + skeletonEl = $('
    ' + + '
    ' + + '
    '); + trEl = skeletonEl.find('tr'); + if (startCol > 0) { + trEl.append(''); + } + trEl.append(seg.el.attr('colspan', endCol - startCol)); + if (endCol < colCnt) { + trEl.append(''); + } + this.component.bookendCells(trEl); + return skeletonEl; + }; + return DayGridFillRenderer; +}(FillRenderer_1.default)); +exports.default = DayGridFillRenderer; + + +/***/ }), +/* 253 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = __webpack_require__(2); +var BasicViewDateProfileGenerator_1 = __webpack_require__(228); +var UnzonedRange_1 = __webpack_require__(5); +var MonthViewDateProfileGenerator = /** @class */ (function (_super) { + tslib_1.__extends(MonthViewDateProfileGenerator, _super); + function MonthViewDateProfileGenerator() { + return _super !== null && _super.apply(this, arguments) || this; + } + // Computes the date range that will be rendered. + MonthViewDateProfileGenerator.prototype.buildRenderRange = function (currentUnzonedRange, currentRangeUnit, isRangeAllDay) { + var renderUnzonedRange = _super.prototype.buildRenderRange.call(this, currentUnzonedRange, currentRangeUnit, isRangeAllDay); + var start = this.msToUtcMoment(renderUnzonedRange.startMs, isRangeAllDay); + var end = this.msToUtcMoment(renderUnzonedRange.endMs, isRangeAllDay); + var rowCnt; + // ensure 6 weeks + if (this.opt('fixedWeekCount')) { + rowCnt = Math.ceil(// could be partial weeks due to hiddenDays + end.diff(start, 'weeks', true) // dontRound=true + ); + end.add(6 - rowCnt, 'weeks'); + } + return new UnzonedRange_1.default(start, end); + }; + return MonthViewDateProfileGenerator; +}(BasicViewDateProfileGenerator_1.default)); +exports.default = MonthViewDateProfileGenerator; + + +/***/ }), +/* 254 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = __webpack_require__(2); +var util_1 = __webpack_require__(4); +var EventRenderer_1 = __webpack_require__(42); +var ListEventRenderer = /** @class */ (function (_super) { + tslib_1.__extends(ListEventRenderer, _super); + function ListEventRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + ListEventRenderer.prototype.renderFgSegs = function (segs) { + if (!segs.length) { + this.component.renderEmptyMessage(); + } + else { + this.component.renderSegList(segs); + } + }; + // generates the HTML for a single event row + ListEventRenderer.prototype.fgSegHtml = function (seg) { + var view = this.view; + var calendar = view.calendar; + var theme = calendar.theme; + var eventFootprint = seg.footprint; + var eventDef = eventFootprint.eventDef; + var componentFootprint = eventFootprint.componentFootprint; + var url = eventDef.url; + var classes = ['fc-list-item'].concat(this.getClasses(eventDef)); + var bgColor = this.getBgColor(eventDef); + var timeHtml; + if (componentFootprint.isAllDay) { + timeHtml = view.getAllDayHtml(); + } + else if (view.isMultiDayRange(componentFootprint.unzonedRange)) { + if (seg.isStart || seg.isEnd) { + timeHtml = util_1.htmlEscape(this._getTimeText(calendar.msToMoment(seg.startMs), calendar.msToMoment(seg.endMs), componentFootprint.isAllDay)); + } + else { + timeHtml = view.getAllDayHtml(); + } + } + else { + // Display the normal time text for the *event's* times + timeHtml = util_1.htmlEscape(this.getTimeText(eventFootprint)); + } + if (url) { + classes.push('fc-has-url'); + } + return '' + + (this.displayEventTime ? + '' + + (timeHtml || '') + + '' : + '') + + '' + + '' + + '' + + '' + + '' + + util_1.htmlEscape(eventDef.title || '') + + '' + + '' + + ''; + }; + // like "4:00am" + ListEventRenderer.prototype.computeEventTimeFormat = function () { + return this.opt('mediumTimeFormat'); + }; + return ListEventRenderer; +}(EventRenderer_1.default)); +exports.default = ListEventRenderer; + + +/***/ }), +/* 255 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = __webpack_require__(2); +var $ = __webpack_require__(3); +var EventPointing_1 = __webpack_require__(59); +var ListEventPointing = /** @class */ (function (_super) { + tslib_1.__extends(ListEventPointing, _super); + function ListEventPointing() { + return _super !== null && _super.apply(this, arguments) || this; + } + // for events with a url, the whole should be clickable, + // but it's impossible to wrap with an tag. simulate this. + ListEventPointing.prototype.handleClick = function (seg, ev) { + var url; + _super.prototype.handleClick.call(this, seg, ev); // might prevent the default action + // not clicking on or within an with an href + if (!$(ev.target).closest('a[href]').length) { + url = seg.footprint.eventDef.url; + if (url && !ev.isDefaultPrevented()) { + window.location.href = url; // simulate link click + } + } + }; + return ListEventPointing; +}(EventPointing_1.default)); +exports.default = ListEventPointing; + + +/***/ }), +/* 256 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var EventSourceParser_1 = __webpack_require__(38); +var ArrayEventSource_1 = __webpack_require__(52); +var FuncEventSource_1 = __webpack_require__(215); +var JsonFeedEventSource_1 = __webpack_require__(216); +EventSourceParser_1.default.registerClass(ArrayEventSource_1.default); +EventSourceParser_1.default.registerClass(FuncEventSource_1.default); +EventSourceParser_1.default.registerClass(JsonFeedEventSource_1.default); + + +/***/ }), +/* 257 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var ThemeRegistry_1 = __webpack_require__(51); +var StandardTheme_1 = __webpack_require__(213); +var JqueryUiTheme_1 = __webpack_require__(214); +var Bootstrap3Theme_1 = __webpack_require__(258); +var Bootstrap4Theme_1 = __webpack_require__(259); +ThemeRegistry_1.defineThemeSystem('standard', StandardTheme_1.default); +ThemeRegistry_1.defineThemeSystem('jquery-ui', JqueryUiTheme_1.default); +ThemeRegistry_1.defineThemeSystem('bootstrap3', Bootstrap3Theme_1.default); +ThemeRegistry_1.defineThemeSystem('bootstrap4', Bootstrap4Theme_1.default); + + +/***/ }), +/* 258 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = __webpack_require__(2); +var Theme_1 = __webpack_require__(19); +var Bootstrap3Theme = /** @class */ (function (_super) { + tslib_1.__extends(Bootstrap3Theme, _super); + function Bootstrap3Theme() { + return _super !== null && _super.apply(this, arguments) || this; + } + return Bootstrap3Theme; +}(Theme_1.default)); +exports.default = Bootstrap3Theme; +Bootstrap3Theme.prototype.classes = { + widget: 'fc-bootstrap3', + tableGrid: 'table-bordered', + tableList: 'table', + tableListHeading: 'active', + buttonGroup: 'btn-group', + button: 'btn btn-default', + stateActive: 'active', + stateDisabled: 'disabled', + today: 'alert alert-info', + popover: 'panel panel-default', + popoverHeader: 'panel-heading', + popoverContent: 'panel-body', + // day grid + // for left/right border color when border is inset from edges (all-day in agenda view) + // avoid `panel` class b/c don't want margins/radius. only border color. + headerRow: 'panel-default', + dayRow: 'panel-default', + // list view + listView: 'panel panel-default' +}; +Bootstrap3Theme.prototype.baseIconClass = 'glyphicon'; +Bootstrap3Theme.prototype.iconClasses = { + close: 'glyphicon-remove', + prev: 'glyphicon-chevron-left', + next: 'glyphicon-chevron-right', + prevYear: 'glyphicon-backward', + nextYear: 'glyphicon-forward' +}; +Bootstrap3Theme.prototype.iconOverrideOption = 'bootstrapGlyphicons'; +Bootstrap3Theme.prototype.iconOverrideCustomButtonOption = 'bootstrapGlyphicon'; +Bootstrap3Theme.prototype.iconOverridePrefix = 'glyphicon-'; + + +/***/ }), +/* 259 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = __webpack_require__(2); +var Theme_1 = __webpack_require__(19); +var Bootstrap4Theme = /** @class */ (function (_super) { + tslib_1.__extends(Bootstrap4Theme, _super); + function Bootstrap4Theme() { + return _super !== null && _super.apply(this, arguments) || this; + } + return Bootstrap4Theme; +}(Theme_1.default)); +exports.default = Bootstrap4Theme; +Bootstrap4Theme.prototype.classes = { + widget: 'fc-bootstrap4', + tableGrid: 'table-bordered', + tableList: 'table', + tableListHeading: 'table-active', + buttonGroup: 'btn-group', + button: 'btn btn-primary', + stateActive: 'active', + stateDisabled: 'disabled', + today: 'alert alert-info', + popover: 'card card-primary', + popoverHeader: 'card-header', + popoverContent: 'card-body', + // day grid + // for left/right border color when border is inset from edges (all-day in agenda view) + // avoid `table` class b/c don't want margins/padding/structure. only border color. + headerRow: 'table-bordered', + dayRow: 'table-bordered', + // list view + listView: 'card card-primary' +}; +Bootstrap4Theme.prototype.baseIconClass = 'fa'; +Bootstrap4Theme.prototype.iconClasses = { + close: 'fa-times', + prev: 'fa-chevron-left', + next: 'fa-chevron-right', + prevYear: 'fa-angle-double-left', + nextYear: 'fa-angle-double-right' +}; +Bootstrap4Theme.prototype.iconOverrideOption = 'bootstrapFontAwesome'; +Bootstrap4Theme.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome'; +Bootstrap4Theme.prototype.iconOverridePrefix = 'fa-'; + + +/***/ }), +/* 260 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var ViewRegistry_1 = __webpack_require__(22); +var BasicView_1 = __webpack_require__(62); +var MonthView_1 = __webpack_require__(229); +ViewRegistry_1.defineView('basic', { + 'class': BasicView_1.default +}); +ViewRegistry_1.defineView('basicDay', { + type: 'basic', + duration: { days: 1 } +}); +ViewRegistry_1.defineView('basicWeek', { + type: 'basic', + duration: { weeks: 1 } +}); +ViewRegistry_1.defineView('month', { + 'class': MonthView_1.default, + duration: { months: 1 }, + defaults: { + fixedWeekCount: true + } +}); + + +/***/ }), +/* 261 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var ViewRegistry_1 = __webpack_require__(22); +var AgendaView_1 = __webpack_require__(226); +ViewRegistry_1.defineView('agenda', { + 'class': AgendaView_1.default, + defaults: { + allDaySlot: true, + slotDuration: '00:30:00', + slotEventOverlap: true // a bad name. confused with overlap/constraint system + } +}); +ViewRegistry_1.defineView('agendaDay', { + type: 'agenda', + duration: { days: 1 } +}); +ViewRegistry_1.defineView('agendaWeek', { + type: 'agenda', + duration: { weeks: 1 } +}); + + +/***/ }), +/* 262 */ +/***/ (function(module, exports, __webpack_require__) { + +Object.defineProperty(exports, "__esModule", { value: true }); +var ViewRegistry_1 = __webpack_require__(22); +var ListView_1 = __webpack_require__(230); +ViewRegistry_1.defineView('list', { + 'class': ListView_1.default, + buttonTextKey: 'list', + defaults: { + buttonText: 'list', + listDayFormat: 'LL', + noEventsMessage: 'No events to display' + } +}); +ViewRegistry_1.defineView('listDay', { + type: 'list', + duration: { days: 1 }, + defaults: { + listDayFormat: 'dddd' // day-of-week is all we need. full date is probably in header + } +}); +ViewRegistry_1.defineView('listWeek', { + type: 'list', + duration: { weeks: 1 }, + defaults: { + listDayFormat: 'dddd', + listDayAltFormat: 'LL' + } +}); +ViewRegistry_1.defineView('listMonth', { + type: 'list', + duration: { month: 1 }, + defaults: { + listDayAltFormat: 'dddd' // day-of-week is nice-to-have + } +}); +ViewRegistry_1.defineView('listYear', { + type: 'list', + duration: { year: 1 }, + defaults: { + listDayAltFormat: 'dddd' // day-of-week is nice-to-have + } +}); + + +/***/ }), +/* 263 */ +/***/ (function(module, exports) { + +Object.defineProperty(exports, "__esModule", { value: true }); + + +/***/ }) +/******/ ]); +}); \ No newline at end of file diff --git a/plugins/calendar/lib/js/moment.js b/plugins/calendar/lib/js/moment.js new file mode 100644 index 00000000..3ec5d3d5 --- /dev/null +++ b/plugins/calendar/lib/js/moment.js @@ -0,0 +1,4511 @@ +//! moment.js + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + global.moment = factory() +}(this, (function () { 'use strict'; + + var hookCallback; + + function hooks () { + return hookCallback.apply(null, arguments); + } + + // This is done to register the method called with moment() + // without creating circular dependencies. + function setHookCallback (callback) { + hookCallback = callback; + } + + function isArray(input) { + return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; + } + + function isObject(input) { + // IE8 will treat undefined and null as object if it wasn't for + // input != null + return input != null && Object.prototype.toString.call(input) === '[object Object]'; + } + + function isObjectEmpty(obj) { + if (Object.getOwnPropertyNames) { + return (Object.getOwnPropertyNames(obj).length === 0); + } else { + var k; + for (k in obj) { + if (obj.hasOwnProperty(k)) { + return false; + } + } + return true; + } + } + + function isUndefined(input) { + return input === void 0; + } + + function isNumber(input) { + return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; + } + + function isDate(input) { + return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; + } + + function map(arr, fn) { + var res = [], i; + for (i = 0; i < arr.length; ++i) { + res.push(fn(arr[i], i)); + } + return res; + } + + function hasOwnProp(a, b) { + return Object.prototype.hasOwnProperty.call(a, b); + } + + function extend(a, b) { + for (var i in b) { + if (hasOwnProp(b, i)) { + a[i] = b[i]; + } + } + + if (hasOwnProp(b, 'toString')) { + a.toString = b.toString; + } + + if (hasOwnProp(b, 'valueOf')) { + a.valueOf = b.valueOf; + } + + return a; + } + + function createUTC (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, true).utc(); + } + + function defaultParsingFlags() { + // We need to deep clone this object. + return { + empty : false, + unusedTokens : [], + unusedInput : [], + overflow : -2, + charsLeftOver : 0, + nullInput : false, + invalidMonth : null, + invalidFormat : false, + userInvalidated : false, + iso : false, + parsedDateParts : [], + meridiem : null, + rfc2822 : false, + weekdayMismatch : false + }; + } + + function getParsingFlags(m) { + if (m._pf == null) { + m._pf = defaultParsingFlags(); + } + return m._pf; + } + + var some; + if (Array.prototype.some) { + some = Array.prototype.some; + } else { + some = function (fun) { + var t = Object(this); + var len = t.length >>> 0; + + for (var i = 0; i < len; i++) { + if (i in t && fun.call(this, t[i], i, t)) { + return true; + } + } + + return false; + }; + } + + function isValid(m) { + if (m._isValid == null) { + var flags = getParsingFlags(m); + var parsedParts = some.call(flags.parsedDateParts, function (i) { + return i != null; + }); + var isNowValid = !isNaN(m._d.getTime()) && + flags.overflow < 0 && + !flags.empty && + !flags.invalidMonth && + !flags.invalidWeekday && + !flags.weekdayMismatch && + !flags.nullInput && + !flags.invalidFormat && + !flags.userInvalidated && + (!flags.meridiem || (flags.meridiem && parsedParts)); + + if (m._strict) { + isNowValid = isNowValid && + flags.charsLeftOver === 0 && + flags.unusedTokens.length === 0 && + flags.bigHour === undefined; + } + + if (Object.isFrozen == null || !Object.isFrozen(m)) { + m._isValid = isNowValid; + } + else { + return isNowValid; + } + } + return m._isValid; + } + + function createInvalid (flags) { + var m = createUTC(NaN); + if (flags != null) { + extend(getParsingFlags(m), flags); + } + else { + getParsingFlags(m).userInvalidated = true; + } + + return m; + } + + // Plugins that add properties should also add the key here (null value), + // so we can properly clone ourselves. + var momentProperties = hooks.momentProperties = []; + + function copyConfig(to, from) { + var i, prop, val; + + if (!isUndefined(from._isAMomentObject)) { + to._isAMomentObject = from._isAMomentObject; + } + if (!isUndefined(from._i)) { + to._i = from._i; + } + if (!isUndefined(from._f)) { + to._f = from._f; + } + if (!isUndefined(from._l)) { + to._l = from._l; + } + if (!isUndefined(from._strict)) { + to._strict = from._strict; + } + if (!isUndefined(from._tzm)) { + to._tzm = from._tzm; + } + if (!isUndefined(from._isUTC)) { + to._isUTC = from._isUTC; + } + if (!isUndefined(from._offset)) { + to._offset = from._offset; + } + if (!isUndefined(from._pf)) { + to._pf = getParsingFlags(from); + } + if (!isUndefined(from._locale)) { + to._locale = from._locale; + } + + if (momentProperties.length > 0) { + for (i = 0; i < momentProperties.length; i++) { + prop = momentProperties[i]; + val = from[prop]; + if (!isUndefined(val)) { + to[prop] = val; + } + } + } + + return to; + } + + var updateInProgress = false; + + // Moment prototype object + function Moment(config) { + copyConfig(this, config); + this._d = new Date(config._d != null ? config._d.getTime() : NaN); + if (!this.isValid()) { + this._d = new Date(NaN); + } + // Prevent infinite loop in case updateOffset creates new moment + // objects. + if (updateInProgress === false) { + updateInProgress = true; + hooks.updateOffset(this); + updateInProgress = false; + } + } + + function isMoment (obj) { + return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); + } + + function absFloor (number) { + if (number < 0) { + // -0 -> 0 + return Math.ceil(number) || 0; + } else { + return Math.floor(number); + } + } + + function toInt(argumentForCoercion) { + var coercedNumber = +argumentForCoercion, + value = 0; + + if (coercedNumber !== 0 && isFinite(coercedNumber)) { + value = absFloor(coercedNumber); + } + + return value; + } + + // compare two arrays, return the number of differences + function compareArrays(array1, array2, dontConvert) { + var len = Math.min(array1.length, array2.length), + lengthDiff = Math.abs(array1.length - array2.length), + diffs = 0, + i; + for (i = 0; i < len; i++) { + if ((dontConvert && array1[i] !== array2[i]) || + (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { + diffs++; + } + } + return diffs + lengthDiff; + } + + function warn(msg) { + if (hooks.suppressDeprecationWarnings === false && + (typeof console !== 'undefined') && console.warn) { + console.warn('Deprecation warning: ' + msg); + } + } + + function deprecate(msg, fn) { + var firstTime = true; + + return extend(function () { + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(null, msg); + } + if (firstTime) { + var args = []; + var arg; + for (var i = 0; i < arguments.length; i++) { + arg = ''; + if (typeof arguments[i] === 'object') { + arg += '\n[' + i + '] '; + for (var key in arguments[0]) { + arg += key + ': ' + arguments[0][key] + ', '; + } + arg = arg.slice(0, -2); // Remove trailing comma and space + } else { + arg = arguments[i]; + } + args.push(arg); + } + warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack); + firstTime = false; + } + return fn.apply(this, arguments); + }, fn); + } + + var deprecations = {}; + + function deprecateSimple(name, msg) { + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(name, msg); + } + if (!deprecations[name]) { + warn(msg); + deprecations[name] = true; + } + } + + hooks.suppressDeprecationWarnings = false; + hooks.deprecationHandler = null; + + function isFunction(input) { + return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; + } + + function set (config) { + var prop, i; + for (i in config) { + prop = config[i]; + if (isFunction(prop)) { + this[i] = prop; + } else { + this['_' + i] = prop; + } + } + this._config = config; + // Lenient ordinal parsing accepts just a number in addition to + // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. + // TODO: Remove "ordinalParse" fallback in next major release. + this._dayOfMonthOrdinalParseLenient = new RegExp( + (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + + '|' + (/\d{1,2}/).source); + } + + function mergeConfigs(parentConfig, childConfig) { + var res = extend({}, parentConfig), prop; + for (prop in childConfig) { + if (hasOwnProp(childConfig, prop)) { + if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { + res[prop] = {}; + extend(res[prop], parentConfig[prop]); + extend(res[prop], childConfig[prop]); + } else if (childConfig[prop] != null) { + res[prop] = childConfig[prop]; + } else { + delete res[prop]; + } + } + } + for (prop in parentConfig) { + if (hasOwnProp(parentConfig, prop) && + !hasOwnProp(childConfig, prop) && + isObject(parentConfig[prop])) { + // make sure changes to properties don't modify parent config + res[prop] = extend({}, res[prop]); + } + } + return res; + } + + function Locale(config) { + if (config != null) { + this.set(config); + } + } + + var keys; + + if (Object.keys) { + keys = Object.keys; + } else { + keys = function (obj) { + var i, res = []; + for (i in obj) { + if (hasOwnProp(obj, i)) { + res.push(i); + } + } + return res; + }; + } + + var defaultCalendar = { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }; + + function calendar (key, mom, now) { + var output = this._calendar[key] || this._calendar['sameElse']; + return isFunction(output) ? output.call(mom, now) : output; + } + + var defaultLongDateFormat = { + LTS : 'h:mm:ss A', + LT : 'h:mm A', + L : 'MM/DD/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY h:mm A', + LLLL : 'dddd, MMMM D, YYYY h:mm A' + }; + + function longDateFormat (key) { + var format = this._longDateFormat[key], + formatUpper = this._longDateFormat[key.toUpperCase()]; + + if (format || !formatUpper) { + return format; + } + + this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { + return val.slice(1); + }); + + return this._longDateFormat[key]; + } + + var defaultInvalidDate = 'Invalid date'; + + function invalidDate () { + return this._invalidDate; + } + + var defaultOrdinal = '%d'; + var defaultDayOfMonthOrdinalParse = /\d{1,2}/; + + function ordinal (number) { + return this._ordinal.replace('%d', number); + } + + var defaultRelativeTime = { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }; + + function relativeTime (number, withoutSuffix, string, isFuture) { + var output = this._relativeTime[string]; + return (isFunction(output)) ? + output(number, withoutSuffix, string, isFuture) : + output.replace(/%d/i, number); + } + + function pastFuture (diff, output) { + var format = this._relativeTime[diff > 0 ? 'future' : 'past']; + return isFunction(format) ? format(output) : format.replace(/%s/i, output); + } + + var aliases = {}; + + function addUnitAlias (unit, shorthand) { + var lowerCase = unit.toLowerCase(); + aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; + } + + function normalizeUnits(units) { + return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; + } + + function normalizeObjectUnits(inputObject) { + var normalizedInput = {}, + normalizedProp, + prop; + + for (prop in inputObject) { + if (hasOwnProp(inputObject, prop)) { + normalizedProp = normalizeUnits(prop); + if (normalizedProp) { + normalizedInput[normalizedProp] = inputObject[prop]; + } + } + } + + return normalizedInput; + } + + var priorities = {}; + + function addUnitPriority(unit, priority) { + priorities[unit] = priority; + } + + function getPrioritizedUnits(unitsObj) { + var units = []; + for (var u in unitsObj) { + units.push({unit: u, priority: priorities[u]}); + } + units.sort(function (a, b) { + return a.priority - b.priority; + }); + return units; + } + + function zeroFill(number, targetLength, forceSign) { + var absNumber = '' + Math.abs(number), + zerosToFill = targetLength - absNumber.length, + sign = number >= 0; + return (sign ? (forceSign ? '+' : '') : '-') + + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; + } + + var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; + + var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; + + var formatFunctions = {}; + + var formatTokenFunctions = {}; + + // token: 'M' + // padded: ['MM', 2] + // ordinal: 'Mo' + // callback: function () { this.month() + 1 } + function addFormatToken (token, padded, ordinal, callback) { + var func = callback; + if (typeof callback === 'string') { + func = function () { + return this[callback](); + }; + } + if (token) { + formatTokenFunctions[token] = func; + } + if (padded) { + formatTokenFunctions[padded[0]] = function () { + return zeroFill(func.apply(this, arguments), padded[1], padded[2]); + }; + } + if (ordinal) { + formatTokenFunctions[ordinal] = function () { + return this.localeData().ordinal(func.apply(this, arguments), token); + }; + } + } + + function removeFormattingTokens(input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|\]$/g, ''); + } + return input.replace(/\\/g, ''); + } + + function makeFormatFunction(format) { + var array = format.match(formattingTokens), i, length; + + for (i = 0, length = array.length; i < length; i++) { + if (formatTokenFunctions[array[i]]) { + array[i] = formatTokenFunctions[array[i]]; + } else { + array[i] = removeFormattingTokens(array[i]); + } + } + + return function (mom) { + var output = '', i; + for (i = 0; i < length; i++) { + output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; + } + return output; + }; + } + + // format date using native date object + function formatMoment(m, format) { + if (!m.isValid()) { + return m.localeData().invalidDate(); + } + + format = expandFormat(format, m.localeData()); + formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); + + return formatFunctions[format](m); + } + + function expandFormat(format, locale) { + var i = 5; + + function replaceLongDateFormatTokens(input) { + return locale.longDateFormat(input) || input; + } + + localFormattingTokens.lastIndex = 0; + while (i >= 0 && localFormattingTokens.test(format)) { + format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); + localFormattingTokens.lastIndex = 0; + i -= 1; + } + + return format; + } + + var match1 = /\d/; // 0 - 9 + var match2 = /\d\d/; // 00 - 99 + var match3 = /\d{3}/; // 000 - 999 + var match4 = /\d{4}/; // 0000 - 9999 + var match6 = /[+-]?\d{6}/; // -999999 - 999999 + var match1to2 = /\d\d?/; // 0 - 99 + var match3to4 = /\d\d\d\d?/; // 999 - 9999 + var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 + var match1to3 = /\d{1,3}/; // 0 - 999 + var match1to4 = /\d{1,4}/; // 0 - 9999 + var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 + + var matchUnsigned = /\d+/; // 0 - inf + var matchSigned = /[+-]?\d+/; // -inf - inf + + var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z + var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z + + var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 + + // any word (or two) characters or numbers including two/three word month in arabic. + // includes scottish gaelic two word and hyphenated months + var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i; + + var regexes = {}; + + function addRegexToken (token, regex, strictRegex) { + regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { + return (isStrict && strictRegex) ? strictRegex : regex; + }; + } + + function getParseRegexForToken (token, config) { + if (!hasOwnProp(regexes, token)) { + return new RegExp(unescapeFormat(token)); + } + + return regexes[token](config._strict, config._locale); + } + + // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript + function unescapeFormat(s) { + return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { + return p1 || p2 || p3 || p4; + })); + } + + function regexEscape(s) { + return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); + } + + var tokens = {}; + + function addParseToken (token, callback) { + var i, func = callback; + if (typeof token === 'string') { + token = [token]; + } + if (isNumber(callback)) { + func = function (input, array) { + array[callback] = toInt(input); + }; + } + for (i = 0; i < token.length; i++) { + tokens[token[i]] = func; + } + } + + function addWeekParseToken (token, callback) { + addParseToken(token, function (input, array, config, token) { + config._w = config._w || {}; + callback(input, config._w, config, token); + }); + } + + function addTimeToArrayFromToken(token, input, config) { + if (input != null && hasOwnProp(tokens, token)) { + tokens[token](input, config._a, config, token); + } + } + + var YEAR = 0; + var MONTH = 1; + var DATE = 2; + var HOUR = 3; + var MINUTE = 4; + var SECOND = 5; + var MILLISECOND = 6; + var WEEK = 7; + var WEEKDAY = 8; + + // FORMATTING + + addFormatToken('Y', 0, 0, function () { + var y = this.year(); + return y <= 9999 ? '' + y : '+' + y; + }); + + addFormatToken(0, ['YY', 2], 0, function () { + return this.year() % 100; + }); + + addFormatToken(0, ['YYYY', 4], 0, 'year'); + addFormatToken(0, ['YYYYY', 5], 0, 'year'); + addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); + + // ALIASES + + addUnitAlias('year', 'y'); + + // PRIORITIES + + addUnitPriority('year', 1); + + // PARSING + + addRegexToken('Y', matchSigned); + addRegexToken('YY', match1to2, match2); + addRegexToken('YYYY', match1to4, match4); + addRegexToken('YYYYY', match1to6, match6); + addRegexToken('YYYYYY', match1to6, match6); + + addParseToken(['YYYYY', 'YYYYYY'], YEAR); + addParseToken('YYYY', function (input, array) { + array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); + }); + addParseToken('YY', function (input, array) { + array[YEAR] = hooks.parseTwoDigitYear(input); + }); + addParseToken('Y', function (input, array) { + array[YEAR] = parseInt(input, 10); + }); + + // HELPERS + + function daysInYear(year) { + return isLeapYear(year) ? 366 : 365; + } + + function isLeapYear(year) { + return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; + } + + // HOOKS + + hooks.parseTwoDigitYear = function (input) { + return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); + }; + + // MOMENTS + + var getSetYear = makeGetSet('FullYear', true); + + function getIsLeapYear () { + return isLeapYear(this.year()); + } + + function makeGetSet (unit, keepTime) { + return function (value) { + if (value != null) { + set$1(this, unit, value); + hooks.updateOffset(this, keepTime); + return this; + } else { + return get(this, unit); + } + }; + } + + function get (mom, unit) { + return mom.isValid() ? + mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; + } + + function set$1 (mom, unit, value) { + if (mom.isValid() && !isNaN(value)) { + if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); + } + else { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } + } + } + + // MOMENTS + + function stringGet (units) { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](); + } + return this; + } + + + function stringSet (units, value) { + if (typeof units === 'object') { + units = normalizeObjectUnits(units); + var prioritized = getPrioritizedUnits(units); + for (var i = 0; i < prioritized.length; i++) { + this[prioritized[i].unit](units[prioritized[i].unit]); + } + } else { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](value); + } + } + return this; + } + + function mod(n, x) { + return ((n % x) + x) % x; + } + + var indexOf; + + if (Array.prototype.indexOf) { + indexOf = Array.prototype.indexOf; + } else { + indexOf = function (o) { + // I know + var i; + for (i = 0; i < this.length; ++i) { + if (this[i] === o) { + return i; + } + } + return -1; + }; + } + + function daysInMonth(year, month) { + if (isNaN(year) || isNaN(month)) { + return NaN; + } + var modMonth = mod(month, 12); + year += (month - modMonth) / 12; + return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); + } + + // FORMATTING + + addFormatToken('M', ['MM', 2], 'Mo', function () { + return this.month() + 1; + }); + + addFormatToken('MMM', 0, 0, function (format) { + return this.localeData().monthsShort(this, format); + }); + + addFormatToken('MMMM', 0, 0, function (format) { + return this.localeData().months(this, format); + }); + + // ALIASES + + addUnitAlias('month', 'M'); + + // PRIORITY + + addUnitPriority('month', 8); + + // PARSING + + addRegexToken('M', match1to2); + addRegexToken('MM', match1to2, match2); + addRegexToken('MMM', function (isStrict, locale) { + return locale.monthsShortRegex(isStrict); + }); + addRegexToken('MMMM', function (isStrict, locale) { + return locale.monthsRegex(isStrict); + }); + + addParseToken(['M', 'MM'], function (input, array) { + array[MONTH] = toInt(input) - 1; + }); + + addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { + var month = config._locale.monthsParse(input, token, config._strict); + // if we didn't find a month name, mark the date as invalid. + if (month != null) { + array[MONTH] = month; + } else { + getParsingFlags(config).invalidMonth = input; + } + }); + + // LOCALES + + var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; + var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); + function localeMonths (m, format) { + if (!m) { + return isArray(this._months) ? this._months : + this._months['standalone']; + } + return isArray(this._months) ? this._months[m.month()] : + this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; + } + + var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); + function localeMonthsShort (m, format) { + if (!m) { + return isArray(this._monthsShort) ? this._monthsShort : + this._monthsShort['standalone']; + } + return isArray(this._monthsShort) ? this._monthsShort[m.month()] : + this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; + } + + function handleStrictParse(monthName, format, strict) { + var i, ii, mom, llc = monthName.toLocaleLowerCase(); + if (!this._monthsParse) { + // this is not used + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + for (i = 0; i < 12; ++i) { + mom = createUTC([2000, i]); + this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); + this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); + } + } + + if (strict) { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } + } + + function localeMonthsParse (monthName, format, strict) { + var i, mom, regex; + + if (this._monthsParseExact) { + return handleStrictParse.call(this, monthName, format, strict); + } + + if (!this._monthsParse) { + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + } + + // TODO: add sorting + // Sorting makes sure if one month (or abbr) is a prefix of another + // see sorting in computeMonthsParse + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, i]); + if (strict && !this._longMonthsParse[i]) { + this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); + this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); + } + if (!strict && !this._monthsParse[i]) { + regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); + this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { + return i; + } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { + return i; + } else if (!strict && this._monthsParse[i].test(monthName)) { + return i; + } + } + } + + // MOMENTS + + function setMonth (mom, value) { + var dayOfMonth; + + if (!mom.isValid()) { + // No op + return mom; + } + + if (typeof value === 'string') { + if (/^\d+$/.test(value)) { + value = toInt(value); + } else { + value = mom.localeData().monthsParse(value); + // TODO: Another silent failure? + if (!isNumber(value)) { + return mom; + } + } + } + + dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); + mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); + return mom; + } + + function getSetMonth (value) { + if (value != null) { + setMonth(this, value); + hooks.updateOffset(this, true); + return this; + } else { + return get(this, 'Month'); + } + } + + function getDaysInMonth () { + return daysInMonth(this.year(), this.month()); + } + + var defaultMonthsShortRegex = matchWord; + function monthsShortRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsShortStrictRegex; + } else { + return this._monthsShortRegex; + } + } else { + if (!hasOwnProp(this, '_monthsShortRegex')) { + this._monthsShortRegex = defaultMonthsShortRegex; + } + return this._monthsShortStrictRegex && isStrict ? + this._monthsShortStrictRegex : this._monthsShortRegex; + } + } + + var defaultMonthsRegex = matchWord; + function monthsRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsStrictRegex; + } else { + return this._monthsRegex; + } + } else { + if (!hasOwnProp(this, '_monthsRegex')) { + this._monthsRegex = defaultMonthsRegex; + } + return this._monthsStrictRegex && isStrict ? + this._monthsStrictRegex : this._monthsRegex; + } + } + + function computeMonthsParse () { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var shortPieces = [], longPieces = [], mixedPieces = [], + i, mom; + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, i]); + shortPieces.push(this.monthsShort(mom, '')); + longPieces.push(this.months(mom, '')); + mixedPieces.push(this.months(mom, '')); + mixedPieces.push(this.monthsShort(mom, '')); + } + // Sorting makes sure if one month (or abbr) is a prefix of another it + // will match the longer piece. + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 12; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + } + for (i = 0; i < 24; i++) { + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._monthsShortRegex = this._monthsRegex; + this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); + this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); + } + + function createDate (y, m, d, h, M, s, ms) { + // can't just apply() to create a date: + // https://stackoverflow.com/q/181348 + var date = new Date(y, m, d, h, M, s, ms); + + // the date constructor remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0 && isFinite(date.getFullYear())) { + date.setFullYear(y); + } + return date; + } + + function createUTCDate (y) { + var date = new Date(Date.UTC.apply(null, arguments)); + + // the Date.UTC function remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) { + date.setUTCFullYear(y); + } + return date; + } + + // start-of-first-week - start-of-year + function firstWeekOffset(year, dow, doy) { + var // first-week day -- which january is always in the first week (4 for iso, 1 for other) + fwd = 7 + dow - doy, + // first-week day local weekday -- which local weekday is fwd + fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; + + return -fwdlw + fwd - 1; + } + + // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday + function dayOfYearFromWeeks(year, week, weekday, dow, doy) { + var localWeekday = (7 + weekday - dow) % 7, + weekOffset = firstWeekOffset(year, dow, doy), + dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, + resYear, resDayOfYear; + + if (dayOfYear <= 0) { + resYear = year - 1; + resDayOfYear = daysInYear(resYear) + dayOfYear; + } else if (dayOfYear > daysInYear(year)) { + resYear = year + 1; + resDayOfYear = dayOfYear - daysInYear(year); + } else { + resYear = year; + resDayOfYear = dayOfYear; + } + + return { + year: resYear, + dayOfYear: resDayOfYear + }; + } + + function weekOfYear(mom, dow, doy) { + var weekOffset = firstWeekOffset(mom.year(), dow, doy), + week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, + resWeek, resYear; + + if (week < 1) { + resYear = mom.year() - 1; + resWeek = week + weeksInYear(resYear, dow, doy); + } else if (week > weeksInYear(mom.year(), dow, doy)) { + resWeek = week - weeksInYear(mom.year(), dow, doy); + resYear = mom.year() + 1; + } else { + resYear = mom.year(); + resWeek = week; + } + + return { + week: resWeek, + year: resYear + }; + } + + function weeksInYear(year, dow, doy) { + var weekOffset = firstWeekOffset(year, dow, doy), + weekOffsetNext = firstWeekOffset(year + 1, dow, doy); + return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; + } + + // FORMATTING + + addFormatToken('w', ['ww', 2], 'wo', 'week'); + addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); + + // ALIASES + + addUnitAlias('week', 'w'); + addUnitAlias('isoWeek', 'W'); + + // PRIORITIES + + addUnitPriority('week', 5); + addUnitPriority('isoWeek', 5); + + // PARSING + + addRegexToken('w', match1to2); + addRegexToken('ww', match1to2, match2); + addRegexToken('W', match1to2); + addRegexToken('WW', match1to2, match2); + + addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { + week[token.substr(0, 1)] = toInt(input); + }); + + // HELPERS + + // LOCALES + + function localeWeek (mom) { + return weekOfYear(mom, this._week.dow, this._week.doy).week; + } + + var defaultLocaleWeek = { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 6th is the first week of the year. + }; + + function localeFirstDayOfWeek () { + return this._week.dow; + } + + function localeFirstDayOfYear () { + return this._week.doy; + } + + // MOMENTS + + function getSetWeek (input) { + var week = this.localeData().week(this); + return input == null ? week : this.add((input - week) * 7, 'd'); + } + + function getSetISOWeek (input) { + var week = weekOfYear(this, 1, 4).week; + return input == null ? week : this.add((input - week) * 7, 'd'); + } + + // FORMATTING + + addFormatToken('d', 0, 'do', 'day'); + + addFormatToken('dd', 0, 0, function (format) { + return this.localeData().weekdaysMin(this, format); + }); + + addFormatToken('ddd', 0, 0, function (format) { + return this.localeData().weekdaysShort(this, format); + }); + + addFormatToken('dddd', 0, 0, function (format) { + return this.localeData().weekdays(this, format); + }); + + addFormatToken('e', 0, 0, 'weekday'); + addFormatToken('E', 0, 0, 'isoWeekday'); + + // ALIASES + + addUnitAlias('day', 'd'); + addUnitAlias('weekday', 'e'); + addUnitAlias('isoWeekday', 'E'); + + // PRIORITY + addUnitPriority('day', 11); + addUnitPriority('weekday', 11); + addUnitPriority('isoWeekday', 11); + + // PARSING + + addRegexToken('d', match1to2); + addRegexToken('e', match1to2); + addRegexToken('E', match1to2); + addRegexToken('dd', function (isStrict, locale) { + return locale.weekdaysMinRegex(isStrict); + }); + addRegexToken('ddd', function (isStrict, locale) { + return locale.weekdaysShortRegex(isStrict); + }); + addRegexToken('dddd', function (isStrict, locale) { + return locale.weekdaysRegex(isStrict); + }); + + addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { + var weekday = config._locale.weekdaysParse(input, token, config._strict); + // if we didn't get a weekday name, mark the date as invalid + if (weekday != null) { + week.d = weekday; + } else { + getParsingFlags(config).invalidWeekday = input; + } + }); + + addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { + week[token] = toInt(input); + }); + + // HELPERS + + function parseWeekday(input, locale) { + if (typeof input !== 'string') { + return input; + } + + if (!isNaN(input)) { + return parseInt(input, 10); + } + + input = locale.weekdaysParse(input); + if (typeof input === 'number') { + return input; + } + + return null; + } + + function parseIsoWeekday(input, locale) { + if (typeof input === 'string') { + return locale.weekdaysParse(input) % 7 || 7; + } + return isNaN(input) ? null : input; + } + + // LOCALES + + var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); + function localeWeekdays (m, format) { + if (!m) { + return isArray(this._weekdays) ? this._weekdays : + this._weekdays['standalone']; + } + return isArray(this._weekdays) ? this._weekdays[m.day()] : + this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()]; + } + + var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); + function localeWeekdaysShort (m) { + return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort; + } + + var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); + function localeWeekdaysMin (m) { + return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin; + } + + function handleStrictParse$1(weekdayName, format, strict) { + var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._shortWeekdaysParse = []; + this._minWeekdaysParse = []; + + for (i = 0; i < 7; ++i) { + mom = createUTC([2000, 1]).day(i); + this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); + this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); + this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); + } + } + + if (strict) { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } + } + + function localeWeekdaysParse (weekdayName, format, strict) { + var i, mom, regex; + + if (this._weekdaysParseExact) { + return handleStrictParse$1.call(this, weekdayName, format, strict); + } + + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._minWeekdaysParse = []; + this._shortWeekdaysParse = []; + this._fullWeekdaysParse = []; + } + + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + + mom = createUTC([2000, 1]).day(i); + if (strict && !this._fullWeekdaysParse[i]) { + this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i'); + this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i'); + this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i'); + } + if (!this._weekdaysParse[i]) { + regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); + this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { + return i; + } + } + } + + // MOMENTS + + function getSetDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); + if (input != null) { + input = parseWeekday(input, this.localeData()); + return this.add(input - day, 'd'); + } else { + return day; + } + } + + function getSetLocaleDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; + return input == null ? weekday : this.add(input - weekday, 'd'); + } + + function getSetISODayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + + // behaves the same as moment#day except + // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) + // as a setter, sunday should belong to the previous week. + + if (input != null) { + var weekday = parseIsoWeekday(input, this.localeData()); + return this.day(this.day() % 7 ? weekday : weekday - 7); + } else { + return this.day() || 7; + } + } + + var defaultWeekdaysRegex = matchWord; + function weekdaysRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysStrictRegex; + } else { + return this._weekdaysRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysRegex')) { + this._weekdaysRegex = defaultWeekdaysRegex; + } + return this._weekdaysStrictRegex && isStrict ? + this._weekdaysStrictRegex : this._weekdaysRegex; + } + } + + var defaultWeekdaysShortRegex = matchWord; + function weekdaysShortRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysShortStrictRegex; + } else { + return this._weekdaysShortRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysShortRegex')) { + this._weekdaysShortRegex = defaultWeekdaysShortRegex; + } + return this._weekdaysShortStrictRegex && isStrict ? + this._weekdaysShortStrictRegex : this._weekdaysShortRegex; + } + } + + var defaultWeekdaysMinRegex = matchWord; + function weekdaysMinRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysMinStrictRegex; + } else { + return this._weekdaysMinRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysMinRegex')) { + this._weekdaysMinRegex = defaultWeekdaysMinRegex; + } + return this._weekdaysMinStrictRegex && isStrict ? + this._weekdaysMinStrictRegex : this._weekdaysMinRegex; + } + } + + + function computeWeekdaysParse () { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], + i, mom, minp, shortp, longp; + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, 1]).day(i); + minp = this.weekdaysMin(mom, ''); + shortp = this.weekdaysShort(mom, ''); + longp = this.weekdays(mom, ''); + minPieces.push(minp); + shortPieces.push(shortp); + longPieces.push(longp); + mixedPieces.push(minp); + mixedPieces.push(shortp); + mixedPieces.push(longp); + } + // Sorting makes sure if one weekday (or abbr) is a prefix of another it + // will match the longer piece. + minPieces.sort(cmpLenRev); + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 7; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._weekdaysShortRegex = this._weekdaysRegex; + this._weekdaysMinRegex = this._weekdaysRegex; + + this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); + this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); + this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); + } + + // FORMATTING + + function hFormat() { + return this.hours() % 12 || 12; + } + + function kFormat() { + return this.hours() || 24; + } + + addFormatToken('H', ['HH', 2], 0, 'hour'); + addFormatToken('h', ['hh', 2], 0, hFormat); + addFormatToken('k', ['kk', 2], 0, kFormat); + + addFormatToken('hmm', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); + }); + + addFormatToken('hmmss', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); + }); + + addFormatToken('Hmm', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2); + }); + + addFormatToken('Hmmss', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); + }); + + function meridiem (token, lowercase) { + addFormatToken(token, 0, 0, function () { + return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); + }); + } + + meridiem('a', true); + meridiem('A', false); + + // ALIASES + + addUnitAlias('hour', 'h'); + + // PRIORITY + addUnitPriority('hour', 13); + + // PARSING + + function matchMeridiem (isStrict, locale) { + return locale._meridiemParse; + } + + addRegexToken('a', matchMeridiem); + addRegexToken('A', matchMeridiem); + addRegexToken('H', match1to2); + addRegexToken('h', match1to2); + addRegexToken('k', match1to2); + addRegexToken('HH', match1to2, match2); + addRegexToken('hh', match1to2, match2); + addRegexToken('kk', match1to2, match2); + + addRegexToken('hmm', match3to4); + addRegexToken('hmmss', match5to6); + addRegexToken('Hmm', match3to4); + addRegexToken('Hmmss', match5to6); + + addParseToken(['H', 'HH'], HOUR); + addParseToken(['k', 'kk'], function (input, array, config) { + var kInput = toInt(input); + array[HOUR] = kInput === 24 ? 0 : kInput; + }); + addParseToken(['a', 'A'], function (input, array, config) { + config._isPm = config._locale.isPM(input); + config._meridiem = input; + }); + addParseToken(['h', 'hh'], function (input, array, config) { + array[HOUR] = toInt(input); + getParsingFlags(config).bigHour = true; + }); + addParseToken('hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + getParsingFlags(config).bigHour = true; + }); + addParseToken('hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + getParsingFlags(config).bigHour = true; + }); + addParseToken('Hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + }); + addParseToken('Hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + }); + + // LOCALES + + function localeIsPM (input) { + // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays + // Using charAt should be more compatible. + return ((input + '').toLowerCase().charAt(0) === 'p'); + } + + var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; + function localeMeridiem (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'pm' : 'PM'; + } else { + return isLower ? 'am' : 'AM'; + } + } + + + // MOMENTS + + // Setting the hour should keep the time, because the user explicitly + // specified which hour they want. So trying to maintain the same hour (in + // a new timezone) makes sense. Adding/subtracting hours does not follow + // this rule. + var getSetHour = makeGetSet('Hours', true); + + var baseConfig = { + calendar: defaultCalendar, + longDateFormat: defaultLongDateFormat, + invalidDate: defaultInvalidDate, + ordinal: defaultOrdinal, + dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, + relativeTime: defaultRelativeTime, + + months: defaultLocaleMonths, + monthsShort: defaultLocaleMonthsShort, + + week: defaultLocaleWeek, + + weekdays: defaultLocaleWeekdays, + weekdaysMin: defaultLocaleWeekdaysMin, + weekdaysShort: defaultLocaleWeekdaysShort, + + meridiemParse: defaultLocaleMeridiemParse + }; + + // internal storage for locale config files + var locales = {}; + var localeFamilies = {}; + var globalLocale; + + function normalizeLocale(key) { + return key ? key.toLowerCase().replace('_', '-') : key; + } + + // pick the locale from the array + // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each + // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root + function chooseLocale(names) { + var i = 0, j, next, locale, split; + + while (i < names.length) { + split = normalizeLocale(names[i]).split('-'); + j = split.length; + next = normalizeLocale(names[i + 1]); + next = next ? next.split('-') : null; + while (j > 0) { + locale = loadLocale(split.slice(0, j).join('-')); + if (locale) { + return locale; + } + if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { + //the next array item is better than a shallower substring of this one + break; + } + j--; + } + i++; + } + return globalLocale; + } + + function loadLocale(name) { + var oldLocale = null; + // TODO: Find a better way to register and load all the locales in Node + if (!locales[name] && (typeof module !== 'undefined') && + module && module.exports) { + try { + oldLocale = globalLocale._abbr; + var aliasedRequire = require; + aliasedRequire('./locale/' + name); + getSetGlobalLocale(oldLocale); + } catch (e) {} + } + return locales[name]; + } + + // This function will load locale and then set the global locale. If + // no arguments are passed in, it will simply return the current global + // locale key. + function getSetGlobalLocale (key, values) { + var data; + if (key) { + if (isUndefined(values)) { + data = getLocale(key); + } + else { + data = defineLocale(key, values); + } + + if (data) { + // moment.duration._locale = moment._locale = data; + globalLocale = data; + } + else { + if ((typeof console !== 'undefined') && console.warn) { + //warn user if arguments are passed but the locale could not be set + console.warn('Locale ' + key + ' not found. Did you forget to load it?'); + } + } + } + + return globalLocale._abbr; + } + + function defineLocale (name, config) { + if (config !== null) { + var locale, parentConfig = baseConfig; + config.abbr = name; + if (locales[name] != null) { + deprecateSimple('defineLocaleOverride', + 'use moment.updateLocale(localeName, config) to change ' + + 'an existing locale. moment.defineLocale(localeName, ' + + 'config) should only be used for creating a new locale ' + + 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'); + parentConfig = locales[name]._config; + } else if (config.parentLocale != null) { + if (locales[config.parentLocale] != null) { + parentConfig = locales[config.parentLocale]._config; + } else { + locale = loadLocale(config.parentLocale); + if (locale != null) { + parentConfig = locale._config; + } else { + if (!localeFamilies[config.parentLocale]) { + localeFamilies[config.parentLocale] = []; + } + localeFamilies[config.parentLocale].push({ + name: name, + config: config + }); + return null; + } + } + } + locales[name] = new Locale(mergeConfigs(parentConfig, config)); + + if (localeFamilies[name]) { + localeFamilies[name].forEach(function (x) { + defineLocale(x.name, x.config); + }); + } + + // backwards compat for now: also set the locale + // make sure we set the locale AFTER all child locales have been + // created, so we won't end up with the child locale set. + getSetGlobalLocale(name); + + + return locales[name]; + } else { + // useful for testing + delete locales[name]; + return null; + } + } + + function updateLocale(name, config) { + if (config != null) { + var locale, tmpLocale, parentConfig = baseConfig; + // MERGE + tmpLocale = loadLocale(name); + if (tmpLocale != null) { + parentConfig = tmpLocale._config; + } + config = mergeConfigs(parentConfig, config); + locale = new Locale(config); + locale.parentLocale = locales[name]; + locales[name] = locale; + + // backwards compat for now: also set the locale + getSetGlobalLocale(name); + } else { + // pass null for config to unupdate, useful for tests + if (locales[name] != null) { + if (locales[name].parentLocale != null) { + locales[name] = locales[name].parentLocale; + } else if (locales[name] != null) { + delete locales[name]; + } + } + } + return locales[name]; + } + + // returns locale data + function getLocale (key) { + var locale; + + if (key && key._locale && key._locale._abbr) { + key = key._locale._abbr; + } + + if (!key) { + return globalLocale; + } + + if (!isArray(key)) { + //short-circuit everything else + locale = loadLocale(key); + if (locale) { + return locale; + } + key = [key]; + } + + return chooseLocale(key); + } + + function listLocales() { + return keys(locales); + } + + function checkOverflow (m) { + var overflow; + var a = m._a; + + if (a && getParsingFlags(m).overflow === -2) { + overflow = + a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : + a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : + a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : + a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : + a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : + a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : + -1; + + if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { + overflow = DATE; + } + if (getParsingFlags(m)._overflowWeeks && overflow === -1) { + overflow = WEEK; + } + if (getParsingFlags(m)._overflowWeekday && overflow === -1) { + overflow = WEEKDAY; + } + + getParsingFlags(m).overflow = overflow; + } + + return m; + } + + // Pick the first defined of two or three arguments. + function defaults(a, b, c) { + if (a != null) { + return a; + } + if (b != null) { + return b; + } + return c; + } + + function currentDateArray(config) { + // hooks is actually the exported moment object + var nowValue = new Date(hooks.now()); + if (config._useUTC) { + return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; + } + return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; + } + + // convert an array to a date. + // the array should mirror the parameters below + // note: all values past the year are optional and will default to the lowest possible value. + // [year, month, day , hour, minute, second, millisecond] + function configFromArray (config) { + var i, date, input = [], currentDate, expectedWeekday, yearToUse; + + if (config._d) { + return; + } + + currentDate = currentDateArray(config); + + //compute day of the year from weeks and weekdays + if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { + dayOfYearFromWeekInfo(config); + } + + //if the day of the year is set, figure out what it is + if (config._dayOfYear != null) { + yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); + + if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { + getParsingFlags(config)._overflowDayOfYear = true; + } + + date = createUTCDate(yearToUse, 0, config._dayOfYear); + config._a[MONTH] = date.getUTCMonth(); + config._a[DATE] = date.getUTCDate(); + } + + // Default to current date. + // * if no year, month, day of month are given, default to today + // * if day of month is given, default month and year + // * if month is given, default only year + // * if year is given, don't default anything + for (i = 0; i < 3 && config._a[i] == null; ++i) { + config._a[i] = input[i] = currentDate[i]; + } + + // Zero out whatever was not defaulted, including time + for (; i < 7; i++) { + config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; + } + + // Check for 24:00:00.000 + if (config._a[HOUR] === 24 && + config._a[MINUTE] === 0 && + config._a[SECOND] === 0 && + config._a[MILLISECOND] === 0) { + config._nextDay = true; + config._a[HOUR] = 0; + } + + config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); + expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); + + // Apply timezone offset from input. The actual utcOffset can be changed + // with parseZone. + if (config._tzm != null) { + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + } + + if (config._nextDay) { + config._a[HOUR] = 24; + } + + // check for mismatching day of week + if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) { + getParsingFlags(config).weekdayMismatch = true; + } + } + + function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; + + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; + + // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); + week = defaults(w.W, 1); + weekday = defaults(w.E, 1); + if (weekday < 1 || weekday > 7) { + weekdayOverflow = true; + } + } else { + dow = config._locale._week.dow; + doy = config._locale._week.doy; + + var curWeek = weekOfYear(createLocal(), dow, doy); + + weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); + + // Default to current week. + week = defaults(w.w, curWeek.week); + + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + if (weekday < 0 || weekday > 6) { + weekdayOverflow = true; + } + } else if (w.e != null) { + // local weekday -- counting starts from beginning of week + weekday = w.e + dow; + if (w.e < 0 || w.e > 6) { + weekdayOverflow = true; + } + } else { + // default to beginning of week + weekday = dow; + } + } + if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { + getParsingFlags(config)._overflowWeeks = true; + } else if (weekdayOverflow != null) { + getParsingFlags(config)._overflowWeekday = true; + } else { + temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; + } + } + + // iso 8601 regex + // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) + var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; + var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; + + var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; + + var isoDates = [ + ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], + ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], + ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], + ['GGGG-[W]WW', /\d{4}-W\d\d/, false], + ['YYYY-DDD', /\d{4}-\d{3}/], + ['YYYY-MM', /\d{4}-\d\d/, false], + ['YYYYYYMMDD', /[+-]\d{10}/], + ['YYYYMMDD', /\d{8}/], + // YYYYMM is NOT allowed by the standard + ['GGGG[W]WWE', /\d{4}W\d{3}/], + ['GGGG[W]WW', /\d{4}W\d{2}/, false], + ['YYYYDDD', /\d{7}/] + ]; + + // iso time formats and regexes + var isoTimes = [ + ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], + ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], + ['HH:mm:ss', /\d\d:\d\d:\d\d/], + ['HH:mm', /\d\d:\d\d/], + ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], + ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], + ['HHmmss', /\d\d\d\d\d\d/], + ['HHmm', /\d\d\d\d/], + ['HH', /\d\d/] + ]; + + var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; + + // date from iso format + function configFromISO(config) { + var i, l, + string = config._i, + match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), + allowTime, dateFormat, timeFormat, tzFormat; + + if (match) { + getParsingFlags(config).iso = true; + + for (i = 0, l = isoDates.length; i < l; i++) { + if (isoDates[i][1].exec(match[1])) { + dateFormat = isoDates[i][0]; + allowTime = isoDates[i][2] !== false; + break; + } + } + if (dateFormat == null) { + config._isValid = false; + return; + } + if (match[3]) { + for (i = 0, l = isoTimes.length; i < l; i++) { + if (isoTimes[i][1].exec(match[3])) { + // match[2] should be 'T' or space + timeFormat = (match[2] || ' ') + isoTimes[i][0]; + break; + } + } + if (timeFormat == null) { + config._isValid = false; + return; + } + } + if (!allowTime && timeFormat != null) { + config._isValid = false; + return; + } + if (match[4]) { + if (tzRegex.exec(match[4])) { + tzFormat = 'Z'; + } else { + config._isValid = false; + return; + } + } + config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); + configFromStringAndFormat(config); + } else { + config._isValid = false; + } + } + + // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 + var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; + + function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { + var result = [ + untruncateYear(yearStr), + defaultLocaleMonthsShort.indexOf(monthStr), + parseInt(dayStr, 10), + parseInt(hourStr, 10), + parseInt(minuteStr, 10) + ]; + + if (secondStr) { + result.push(parseInt(secondStr, 10)); + } + + return result; + } + + function untruncateYear(yearStr) { + var year = parseInt(yearStr, 10); + if (year <= 49) { + return 2000 + year; + } else if (year <= 999) { + return 1900 + year; + } + return year; + } + + function preprocessRFC2822(s) { + // Remove comments and folding whitespace and replace multiple-spaces with a single space + return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + } + + function checkWeekday(weekdayStr, parsedInput, config) { + if (weekdayStr) { + // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. + var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), + weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); + if (weekdayProvided !== weekdayActual) { + getParsingFlags(config).weekdayMismatch = true; + config._isValid = false; + return false; + } + } + return true; + } + + var obsOffsets = { + UT: 0, + GMT: 0, + EDT: -4 * 60, + EST: -5 * 60, + CDT: -5 * 60, + CST: -6 * 60, + MDT: -6 * 60, + MST: -7 * 60, + PDT: -7 * 60, + PST: -8 * 60 + }; + + function calculateOffset(obsOffset, militaryOffset, numOffset) { + if (obsOffset) { + return obsOffsets[obsOffset]; + } else if (militaryOffset) { + // the only allowed military tz is Z + return 0; + } else { + var hm = parseInt(numOffset, 10); + var m = hm % 100, h = (hm - m) / 100; + return h * 60 + m; + } + } + + // date and time from ref 2822 format + function configFromRFC2822(config) { + var match = rfc2822.exec(preprocessRFC2822(config._i)); + if (match) { + var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); + if (!checkWeekday(match[1], parsedArray, config)) { + return; + } + + config._a = parsedArray; + config._tzm = calculateOffset(match[8], match[9], match[10]); + + config._d = createUTCDate.apply(null, config._a); + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + + getParsingFlags(config).rfc2822 = true; + } else { + config._isValid = false; + } + } + + // date from iso format or fallback + function configFromString(config) { + var matched = aspNetJsonRegex.exec(config._i); + + if (matched !== null) { + config._d = new Date(+matched[1]); + return; + } + + configFromISO(config); + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } + + configFromRFC2822(config); + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } + + // Final attempt, use Input Fallback + hooks.createFromInputFallback(config); + } + + hooks.createFromInputFallback = deprecate( + 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + + 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + + 'discouraged and will be removed in an upcoming major release. Please refer to ' + + 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', + function (config) { + config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); + } + ); + + // constant that refers to the ISO standard + hooks.ISO_8601 = function () {}; + + // constant that refers to the RFC 2822 form + hooks.RFC_2822 = function () {}; + + // date from string and format string + function configFromStringAndFormat(config) { + // TODO: Move this to another part of the creation flow to prevent circular deps + if (config._f === hooks.ISO_8601) { + configFromISO(config); + return; + } + if (config._f === hooks.RFC_2822) { + configFromRFC2822(config); + return; + } + config._a = []; + getParsingFlags(config).empty = true; + + // This array is used to make a Date, either with `new Date` or `Date.UTC` + var string = '' + config._i, + i, parsedInput, tokens, token, skipped, + stringLength = string.length, + totalParsedInputLength = 0; + + tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; + + for (i = 0; i < tokens.length; i++) { + token = tokens[i]; + parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; + // console.log('token', token, 'parsedInput', parsedInput, + // 'regex', getParseRegexForToken(token, config)); + if (parsedInput) { + skipped = string.substr(0, string.indexOf(parsedInput)); + if (skipped.length > 0) { + getParsingFlags(config).unusedInput.push(skipped); + } + string = string.slice(string.indexOf(parsedInput) + parsedInput.length); + totalParsedInputLength += parsedInput.length; + } + // don't parse if it's not a known token + if (formatTokenFunctions[token]) { + if (parsedInput) { + getParsingFlags(config).empty = false; + } + else { + getParsingFlags(config).unusedTokens.push(token); + } + addTimeToArrayFromToken(token, parsedInput, config); + } + else if (config._strict && !parsedInput) { + getParsingFlags(config).unusedTokens.push(token); + } + } + + // add remaining unparsed input length to the string + getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; + if (string.length > 0) { + getParsingFlags(config).unusedInput.push(string); + } + + // clear _12h flag if hour is <= 12 + if (config._a[HOUR] <= 12 && + getParsingFlags(config).bigHour === true && + config._a[HOUR] > 0) { + getParsingFlags(config).bigHour = undefined; + } + + getParsingFlags(config).parsedDateParts = config._a.slice(0); + getParsingFlags(config).meridiem = config._meridiem; + // handle meridiem + config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); + + configFromArray(config); + checkOverflow(config); + } + + + function meridiemFixWrap (locale, hour, meridiem) { + var isPm; + + if (meridiem == null) { + // nothing to do + return hour; + } + if (locale.meridiemHour != null) { + return locale.meridiemHour(hour, meridiem); + } else if (locale.isPM != null) { + // Fallback + isPm = locale.isPM(meridiem); + if (isPm && hour < 12) { + hour += 12; + } + if (!isPm && hour === 12) { + hour = 0; + } + return hour; + } else { + // this is not supposed to happen + return hour; + } + } + + // date from string and array of format strings + function configFromStringAndArray(config) { + var tempConfig, + bestMoment, + + scoreToBeat, + i, + currentScore; + + if (config._f.length === 0) { + getParsingFlags(config).invalidFormat = true; + config._d = new Date(NaN); + return; + } + + for (i = 0; i < config._f.length; i++) { + currentScore = 0; + tempConfig = copyConfig({}, config); + if (config._useUTC != null) { + tempConfig._useUTC = config._useUTC; + } + tempConfig._f = config._f[i]; + configFromStringAndFormat(tempConfig); + + if (!isValid(tempConfig)) { + continue; + } + + // if there is any input that was not parsed add a penalty for that format + currentScore += getParsingFlags(tempConfig).charsLeftOver; + + //or tokens + currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; + + getParsingFlags(tempConfig).score = currentScore; + + if (scoreToBeat == null || currentScore < scoreToBeat) { + scoreToBeat = currentScore; + bestMoment = tempConfig; + } + } + + extend(config, bestMoment || tempConfig); + } + + function configFromObject(config) { + if (config._d) { + return; + } + + var i = normalizeObjectUnits(config._i); + config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { + return obj && parseInt(obj, 10); + }); + + configFromArray(config); + } + + function createFromConfig (config) { + var res = new Moment(checkOverflow(prepareConfig(config))); + if (res._nextDay) { + // Adding is smart enough around DST + res.add(1, 'd'); + res._nextDay = undefined; + } + + return res; + } + + function prepareConfig (config) { + var input = config._i, + format = config._f; + + config._locale = config._locale || getLocale(config._l); + + if (input === null || (format === undefined && input === '')) { + return createInvalid({nullInput: true}); + } + + if (typeof input === 'string') { + config._i = input = config._locale.preparse(input); + } + + if (isMoment(input)) { + return new Moment(checkOverflow(input)); + } else if (isDate(input)) { + config._d = input; + } else if (isArray(format)) { + configFromStringAndArray(config); + } else if (format) { + configFromStringAndFormat(config); + } else { + configFromInput(config); + } + + if (!isValid(config)) { + config._d = null; + } + + return config; + } + + function configFromInput(config) { + var input = config._i; + if (isUndefined(input)) { + config._d = new Date(hooks.now()); + } else if (isDate(input)) { + config._d = new Date(input.valueOf()); + } else if (typeof input === 'string') { + configFromString(config); + } else if (isArray(input)) { + config._a = map(input.slice(0), function (obj) { + return parseInt(obj, 10); + }); + configFromArray(config); + } else if (isObject(input)) { + configFromObject(config); + } else if (isNumber(input)) { + // from milliseconds + config._d = new Date(input); + } else { + hooks.createFromInputFallback(config); + } + } + + function createLocalOrUTC (input, format, locale, strict, isUTC) { + var c = {}; + + if (locale === true || locale === false) { + strict = locale; + locale = undefined; + } + + if ((isObject(input) && isObjectEmpty(input)) || + (isArray(input) && input.length === 0)) { + input = undefined; + } + // object construction must be done this way. + // https://github.com/moment/moment/issues/1423 + c._isAMomentObject = true; + c._useUTC = c._isUTC = isUTC; + c._l = locale; + c._i = input; + c._f = format; + c._strict = strict; + + return createFromConfig(c); + } + + function createLocal (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, false); + } + + var prototypeMin = deprecate( + 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', + function () { + var other = createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other < this ? this : other; + } else { + return createInvalid(); + } + } + ); + + var prototypeMax = deprecate( + 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', + function () { + var other = createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other > this ? this : other; + } else { + return createInvalid(); + } + } + ); + + // Pick a moment m from moments so that m[fn](other) is true for all + // other. This relies on the function fn to be transitive. + // + // moments should either be an array of moment objects or an array, whose + // first element is an array of moment objects. + function pickBy(fn, moments) { + var res, i; + if (moments.length === 1 && isArray(moments[0])) { + moments = moments[0]; + } + if (!moments.length) { + return createLocal(); + } + res = moments[0]; + for (i = 1; i < moments.length; ++i) { + if (!moments[i].isValid() || moments[i][fn](res)) { + res = moments[i]; + } + } + return res; + } + + // TODO: Use [].sort instead? + function min () { + var args = [].slice.call(arguments, 0); + + return pickBy('isBefore', args); + } + + function max () { + var args = [].slice.call(arguments, 0); + + return pickBy('isAfter', args); + } + + var now = function () { + return Date.now ? Date.now() : +(new Date()); + }; + + var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; + + function isDurationValid(m) { + for (var key in m) { + if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { + return false; + } + } + + var unitHasDecimal = false; + for (var i = 0; i < ordering.length; ++i) { + if (m[ordering[i]]) { + if (unitHasDecimal) { + return false; // only allow non-integers for smallest unit + } + if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { + unitHasDecimal = true; + } + } + } + + return true; + } + + function isValid$1() { + return this._isValid; + } + + function createInvalid$1() { + return createDuration(NaN); + } + + function Duration (duration) { + var normalizedInput = normalizeObjectUnits(duration), + years = normalizedInput.year || 0, + quarters = normalizedInput.quarter || 0, + months = normalizedInput.month || 0, + weeks = normalizedInput.week || normalizedInput.isoWeek || 0, + days = normalizedInput.day || 0, + hours = normalizedInput.hour || 0, + minutes = normalizedInput.minute || 0, + seconds = normalizedInput.second || 0, + milliseconds = normalizedInput.millisecond || 0; + + this._isValid = isDurationValid(normalizedInput); + + // representation for dateAddRemove + this._milliseconds = +milliseconds + + seconds * 1e3 + // 1000 + minutes * 6e4 + // 1000 * 60 + hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 + // Because of dateAddRemove treats 24 hours as different from a + // day when working around DST, we need to store them separately + this._days = +days + + weeks * 7; + // It is impossible to translate months into days without knowing + // which months you are are talking about, so we have to store + // it separately. + this._months = +months + + quarters * 3 + + years * 12; + + this._data = {}; + + this._locale = getLocale(); + + this._bubble(); + } + + function isDuration (obj) { + return obj instanceof Duration; + } + + function absRound (number) { + if (number < 0) { + return Math.round(-1 * number) * -1; + } else { + return Math.round(number); + } + } + + // FORMATTING + + function offset (token, separator) { + addFormatToken(token, 0, 0, function () { + var offset = this.utcOffset(); + var sign = '+'; + if (offset < 0) { + offset = -offset; + sign = '-'; + } + return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); + }); + } + + offset('Z', ':'); + offset('ZZ', ''); + + // PARSING + + addRegexToken('Z', matchShortOffset); + addRegexToken('ZZ', matchShortOffset); + addParseToken(['Z', 'ZZ'], function (input, array, config) { + config._useUTC = true; + config._tzm = offsetFromString(matchShortOffset, input); + }); + + // HELPERS + + // timezone chunker + // '+10:00' > ['10', '00'] + // '-1530' > ['-15', '30'] + var chunkOffset = /([\+\-]|\d\d)/gi; + + function offsetFromString(matcher, string) { + var matches = (string || '').match(matcher); + + if (matches === null) { + return null; + } + + var chunk = matches[matches.length - 1] || []; + var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; + var minutes = +(parts[1] * 60) + toInt(parts[2]); + + return minutes === 0 ? + 0 : + parts[0] === '+' ? minutes : -minutes; + } + + // Return a moment from input, that is local/utc/zone equivalent to model. + function cloneWithOffset(input, model) { + var res, diff; + if (model._isUTC) { + res = model.clone(); + diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); + // Use low-level api, because this fn is low-level api. + res._d.setTime(res._d.valueOf() + diff); + hooks.updateOffset(res, false); + return res; + } else { + return createLocal(input).local(); + } + } + + function getDateOffset (m) { + // On Firefox.24 Date#getTimezoneOffset returns a floating point. + // https://github.com/moment/moment/pull/1871 + return -Math.round(m._d.getTimezoneOffset() / 15) * 15; + } + + // HOOKS + + // This function will be called whenever a moment is mutated. + // It is intended to keep the offset in sync with the timezone. + hooks.updateOffset = function () {}; + + // MOMENTS + + // keepLocalTime = true means only change the timezone, without + // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> + // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset + // +0200, so we adjust the time as needed, to be valid. + // + // Keeping the time actually adds/subtracts (one hour) + // from the actual represented time. That is why we call updateOffset + // a second time. In case it wants us to change the offset again + // _changeInProgress == true case, then we have to adjust, because + // there is no such time in the given timezone. + function getSetOffset (input, keepLocalTime, keepMinutes) { + var offset = this._offset || 0, + localAdjust; + if (!this.isValid()) { + return input != null ? this : NaN; + } + if (input != null) { + if (typeof input === 'string') { + input = offsetFromString(matchShortOffset, input); + if (input === null) { + return this; + } + } else if (Math.abs(input) < 16 && !keepMinutes) { + input = input * 60; + } + if (!this._isUTC && keepLocalTime) { + localAdjust = getDateOffset(this); + } + this._offset = input; + this._isUTC = true; + if (localAdjust != null) { + this.add(localAdjust, 'm'); + } + if (offset !== input) { + if (!keepLocalTime || this._changeInProgress) { + addSubtract(this, createDuration(input - offset, 'm'), 1, false); + } else if (!this._changeInProgress) { + this._changeInProgress = true; + hooks.updateOffset(this, true); + this._changeInProgress = null; + } + } + return this; + } else { + return this._isUTC ? offset : getDateOffset(this); + } + } + + function getSetZone (input, keepLocalTime) { + if (input != null) { + if (typeof input !== 'string') { + input = -input; + } + + this.utcOffset(input, keepLocalTime); + + return this; + } else { + return -this.utcOffset(); + } + } + + function setOffsetToUTC (keepLocalTime) { + return this.utcOffset(0, keepLocalTime); + } + + function setOffsetToLocal (keepLocalTime) { + if (this._isUTC) { + this.utcOffset(0, keepLocalTime); + this._isUTC = false; + + if (keepLocalTime) { + this.subtract(getDateOffset(this), 'm'); + } + } + return this; + } + + function setOffsetToParsedOffset () { + if (this._tzm != null) { + this.utcOffset(this._tzm, false, true); + } else if (typeof this._i === 'string') { + var tZone = offsetFromString(matchOffset, this._i); + if (tZone != null) { + this.utcOffset(tZone); + } + else { + this.utcOffset(0, true); + } + } + return this; + } + + function hasAlignedHourOffset (input) { + if (!this.isValid()) { + return false; + } + input = input ? createLocal(input).utcOffset() : 0; + + return (this.utcOffset() - input) % 60 === 0; + } + + function isDaylightSavingTime () { + return ( + this.utcOffset() > this.clone().month(0).utcOffset() || + this.utcOffset() > this.clone().month(5).utcOffset() + ); + } + + function isDaylightSavingTimeShifted () { + if (!isUndefined(this._isDSTShifted)) { + return this._isDSTShifted; + } + + var c = {}; + + copyConfig(c, this); + c = prepareConfig(c); + + if (c._a) { + var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); + this._isDSTShifted = this.isValid() && + compareArrays(c._a, other.toArray()) > 0; + } else { + this._isDSTShifted = false; + } + + return this._isDSTShifted; + } + + function isLocal () { + return this.isValid() ? !this._isUTC : false; + } + + function isUtcOffset () { + return this.isValid() ? this._isUTC : false; + } + + function isUtc () { + return this.isValid() ? this._isUTC && this._offset === 0 : false; + } + + // ASP.NET json date format regex + var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; + + // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html + // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere + // and further modified to allow for strings containing both week and day + var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; + + function createDuration (input, key) { + var duration = input, + // matching against regexp is expensive, do it on demand + match = null, + sign, + ret, + diffRes; + + if (isDuration(input)) { + duration = { + ms : input._milliseconds, + d : input._days, + M : input._months + }; + } else if (isNumber(input)) { + duration = {}; + if (key) { + duration[key] = input; + } else { + duration.milliseconds = input; + } + } else if (!!(match = aspNetRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : 1; + duration = { + y : 0, + d : toInt(match[DATE]) * sign, + h : toInt(match[HOUR]) * sign, + m : toInt(match[MINUTE]) * sign, + s : toInt(match[SECOND]) * sign, + ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match + }; + } else if (!!(match = isoRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : 1; + duration = { + y : parseIso(match[2], sign), + M : parseIso(match[3], sign), + w : parseIso(match[4], sign), + d : parseIso(match[5], sign), + h : parseIso(match[6], sign), + m : parseIso(match[7], sign), + s : parseIso(match[8], sign) + }; + } else if (duration == null) {// checks for null or undefined + duration = {}; + } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { + diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); + + duration = {}; + duration.ms = diffRes.milliseconds; + duration.M = diffRes.months; + } + + ret = new Duration(duration); + + if (isDuration(input) && hasOwnProp(input, '_locale')) { + ret._locale = input._locale; + } + + return ret; + } + + createDuration.fn = Duration.prototype; + createDuration.invalid = createInvalid$1; + + function parseIso (inp, sign) { + // We'd normally use ~~inp for this, but unfortunately it also + // converts floats to ints. + // inp may be undefined, so careful calling replace on it. + var res = inp && parseFloat(inp.replace(',', '.')); + // apply sign while we're at it + return (isNaN(res) ? 0 : res) * sign; + } + + function positiveMomentsDifference(base, other) { + var res = {milliseconds: 0, months: 0}; + + res.months = other.month() - base.month() + + (other.year() - base.year()) * 12; + if (base.clone().add(res.months, 'M').isAfter(other)) { + --res.months; + } + + res.milliseconds = +other - +(base.clone().add(res.months, 'M')); + + return res; + } + + function momentsDifference(base, other) { + var res; + if (!(base.isValid() && other.isValid())) { + return {milliseconds: 0, months: 0}; + } + + other = cloneWithOffset(other, base); + if (base.isBefore(other)) { + res = positiveMomentsDifference(base, other); + } else { + res = positiveMomentsDifference(other, base); + res.milliseconds = -res.milliseconds; + res.months = -res.months; + } + + return res; + } + + // TODO: remove 'name' arg after deprecation is removed + function createAdder(direction, name) { + return function (val, period) { + var dur, tmp; + //invert the arguments, but complain about it + if (period !== null && !isNaN(+period)) { + deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + + 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'); + tmp = val; val = period; period = tmp; + } + + val = typeof val === 'string' ? +val : val; + dur = createDuration(val, period); + addSubtract(this, dur, direction); + return this; + }; + } + + function addSubtract (mom, duration, isAdding, updateOffset) { + var milliseconds = duration._milliseconds, + days = absRound(duration._days), + months = absRound(duration._months); + + if (!mom.isValid()) { + // No op + return; + } + + updateOffset = updateOffset == null ? true : updateOffset; + + if (months) { + setMonth(mom, get(mom, 'Month') + months * isAdding); + } + if (days) { + set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); + } + if (milliseconds) { + mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); + } + if (updateOffset) { + hooks.updateOffset(mom, days || months); + } + } + + var add = createAdder(1, 'add'); + var subtract = createAdder(-1, 'subtract'); + + function getCalendarFormat(myMoment, now) { + var diff = myMoment.diff(now, 'days', true); + return diff < -6 ? 'sameElse' : + diff < -1 ? 'lastWeek' : + diff < 0 ? 'lastDay' : + diff < 1 ? 'sameDay' : + diff < 2 ? 'nextDay' : + diff < 7 ? 'nextWeek' : 'sameElse'; + } + + function calendar$1 (time, formats) { + // We want to compare the start of today, vs this. + // Getting start-of-today depends on whether we're local/utc/offset or not. + var now = time || createLocal(), + sod = cloneWithOffset(now, this).startOf('day'), + format = hooks.calendarFormat(this, sod) || 'sameElse'; + + var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); + + return this.format(output || this.localeData().calendar(format, this, createLocal(now))); + } + + function clone () { + return new Moment(this); + } + + function isAfter (input, units) { + var localInput = isMoment(input) ? input : createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(units) || 'millisecond'; + if (units === 'millisecond') { + return this.valueOf() > localInput.valueOf(); + } else { + return localInput.valueOf() < this.clone().startOf(units).valueOf(); + } + } + + function isBefore (input, units) { + var localInput = isMoment(input) ? input : createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(units) || 'millisecond'; + if (units === 'millisecond') { + return this.valueOf() < localInput.valueOf(); + } else { + return this.clone().endOf(units).valueOf() < localInput.valueOf(); + } + } + + function isBetween (from, to, units, inclusivity) { + var localFrom = isMoment(from) ? from : createLocal(from), + localTo = isMoment(to) ? to : createLocal(to); + if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) { + return false; + } + inclusivity = inclusivity || '()'; + return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && + (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units)); + } + + function isSame (input, units) { + var localInput = isMoment(input) ? input : createLocal(input), + inputMs; + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(units) || 'millisecond'; + if (units === 'millisecond') { + return this.valueOf() === localInput.valueOf(); + } else { + inputMs = localInput.valueOf(); + return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); + } + } + + function isSameOrAfter (input, units) { + return this.isSame(input, units) || this.isAfter(input, units); + } + + function isSameOrBefore (input, units) { + return this.isSame(input, units) || this.isBefore(input, units); + } + + function diff (input, units, asFloat) { + var that, + zoneDelta, + output; + + if (!this.isValid()) { + return NaN; + } + + that = cloneWithOffset(input, this); + + if (!that.isValid()) { + return NaN; + } + + zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; + + units = normalizeUnits(units); + + switch (units) { + case 'year': output = monthDiff(this, that) / 12; break; + case 'month': output = monthDiff(this, that); break; + case 'quarter': output = monthDiff(this, that) / 3; break; + case 'second': output = (this - that) / 1e3; break; // 1000 + case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 + case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 + case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst + case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst + default: output = this - that; + } + + return asFloat ? output : absFloor(output); + } + + function monthDiff (a, b) { + // difference in months + var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), + // b is in (anchor - 1 month, anchor + 1 month) + anchor = a.clone().add(wholeMonthDiff, 'months'), + anchor2, adjust; + + if (b - anchor < 0) { + anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor - anchor2); + } else { + anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor2 - anchor); + } + + //check for negative zero, return zero if negative zero + return -(wholeMonthDiff + adjust) || 0; + } + + hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; + hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; + + function toString () { + return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); + } + + function toISOString(keepOffset) { + if (!this.isValid()) { + return null; + } + var utc = keepOffset !== true; + var m = utc ? this.clone().utc() : this; + if (m.year() < 0 || m.year() > 9999) { + return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'); + } + if (isFunction(Date.prototype.toISOString)) { + // native implementation is ~50x faster, use it when we can + if (utc) { + return this.toDate().toISOString(); + } else { + return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z')); + } + } + return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'); + } + + /** + * Return a human readable representation of a moment that can + * also be evaluated to get a new moment which is the same + * + * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects + */ + function inspect () { + if (!this.isValid()) { + return 'moment.invalid(/* ' + this._i + ' */)'; + } + var func = 'moment'; + var zone = ''; + if (!this.isLocal()) { + func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; + zone = 'Z'; + } + var prefix = '[' + func + '("]'; + var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY'; + var datetime = '-MM-DD[T]HH:mm:ss.SSS'; + var suffix = zone + '[")]'; + + return this.format(prefix + year + datetime + suffix); + } + + function format (inputString) { + if (!inputString) { + inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; + } + var output = formatMoment(this, inputString); + return this.localeData().postformat(output); + } + + function from (time, withoutSuffix) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + createLocal(time).isValid())) { + return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } + } + + function fromNow (withoutSuffix) { + return this.from(createLocal(), withoutSuffix); + } + + function to (time, withoutSuffix) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + createLocal(time).isValid())) { + return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } + } + + function toNow (withoutSuffix) { + return this.to(createLocal(), withoutSuffix); + } + + // If passed a locale key, it will set the locale for this + // instance. Otherwise, it will return the locale configuration + // variables for this instance. + function locale (key) { + var newLocaleData; + + if (key === undefined) { + return this._locale._abbr; + } else { + newLocaleData = getLocale(key); + if (newLocaleData != null) { + this._locale = newLocaleData; + } + return this; + } + } + + var lang = deprecate( + 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', + function (key) { + if (key === undefined) { + return this.localeData(); + } else { + return this.locale(key); + } + } + ); + + function localeData () { + return this._locale; + } + + function startOf (units) { + units = normalizeUnits(units); + // the following switch intentionally omits break keywords + // to utilize falling through the cases. + switch (units) { + case 'year': + this.month(0); + /* falls through */ + case 'quarter': + case 'month': + this.date(1); + /* falls through */ + case 'week': + case 'isoWeek': + case 'day': + case 'date': + this.hours(0); + /* falls through */ + case 'hour': + this.minutes(0); + /* falls through */ + case 'minute': + this.seconds(0); + /* falls through */ + case 'second': + this.milliseconds(0); + } + + // weeks are a special case + if (units === 'week') { + this.weekday(0); + } + if (units === 'isoWeek') { + this.isoWeekday(1); + } + + // quarters are also special + if (units === 'quarter') { + this.month(Math.floor(this.month() / 3) * 3); + } + + return this; + } + + function endOf (units) { + units = normalizeUnits(units); + if (units === undefined || units === 'millisecond') { + return this; + } + + // 'date' is an alias for 'day', so it should be considered as such. + if (units === 'date') { + units = 'day'; + } + + return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); + } + + function valueOf () { + return this._d.valueOf() - ((this._offset || 0) * 60000); + } + + function unix () { + return Math.floor(this.valueOf() / 1000); + } + + function toDate () { + return new Date(this.valueOf()); + } + + function toArray () { + var m = this; + return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; + } + + function toObject () { + var m = this; + return { + years: m.year(), + months: m.month(), + date: m.date(), + hours: m.hours(), + minutes: m.minutes(), + seconds: m.seconds(), + milliseconds: m.milliseconds() + }; + } + + function toJSON () { + // new Date(NaN).toJSON() === null + return this.isValid() ? this.toISOString() : null; + } + + function isValid$2 () { + return isValid(this); + } + + function parsingFlags () { + return extend({}, getParsingFlags(this)); + } + + function invalidAt () { + return getParsingFlags(this).overflow; + } + + function creationData() { + return { + input: this._i, + format: this._f, + locale: this._locale, + isUTC: this._isUTC, + strict: this._strict + }; + } + + // FORMATTING + + addFormatToken(0, ['gg', 2], 0, function () { + return this.weekYear() % 100; + }); + + addFormatToken(0, ['GG', 2], 0, function () { + return this.isoWeekYear() % 100; + }); + + function addWeekYearFormatToken (token, getter) { + addFormatToken(0, [token, token.length], 0, getter); + } + + addWeekYearFormatToken('gggg', 'weekYear'); + addWeekYearFormatToken('ggggg', 'weekYear'); + addWeekYearFormatToken('GGGG', 'isoWeekYear'); + addWeekYearFormatToken('GGGGG', 'isoWeekYear'); + + // ALIASES + + addUnitAlias('weekYear', 'gg'); + addUnitAlias('isoWeekYear', 'GG'); + + // PRIORITY + + addUnitPriority('weekYear', 1); + addUnitPriority('isoWeekYear', 1); + + + // PARSING + + addRegexToken('G', matchSigned); + addRegexToken('g', matchSigned); + addRegexToken('GG', match1to2, match2); + addRegexToken('gg', match1to2, match2); + addRegexToken('GGGG', match1to4, match4); + addRegexToken('gggg', match1to4, match4); + addRegexToken('GGGGG', match1to6, match6); + addRegexToken('ggggg', match1to6, match6); + + addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { + week[token.substr(0, 2)] = toInt(input); + }); + + addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { + week[token] = hooks.parseTwoDigitYear(input); + }); + + // MOMENTS + + function getSetWeekYear (input) { + return getSetWeekYearHelper.call(this, + input, + this.week(), + this.weekday(), + this.localeData()._week.dow, + this.localeData()._week.doy); + } + + function getSetISOWeekYear (input) { + return getSetWeekYearHelper.call(this, + input, this.isoWeek(), this.isoWeekday(), 1, 4); + } + + function getISOWeeksInYear () { + return weeksInYear(this.year(), 1, 4); + } + + function getWeeksInYear () { + var weekInfo = this.localeData()._week; + return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); + } + + function getSetWeekYearHelper(input, week, weekday, dow, doy) { + var weeksTarget; + if (input == null) { + return weekOfYear(this, dow, doy).year; + } else { + weeksTarget = weeksInYear(input, dow, doy); + if (week > weeksTarget) { + week = weeksTarget; + } + return setWeekAll.call(this, input, week, weekday, dow, doy); + } + } + + function setWeekAll(weekYear, week, weekday, dow, doy) { + var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), + date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); + + this.year(date.getUTCFullYear()); + this.month(date.getUTCMonth()); + this.date(date.getUTCDate()); + return this; + } + + // FORMATTING + + addFormatToken('Q', 0, 'Qo', 'quarter'); + + // ALIASES + + addUnitAlias('quarter', 'Q'); + + // PRIORITY + + addUnitPriority('quarter', 7); + + // PARSING + + addRegexToken('Q', match1); + addParseToken('Q', function (input, array) { + array[MONTH] = (toInt(input) - 1) * 3; + }); + + // MOMENTS + + function getSetQuarter (input) { + return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); + } + + // FORMATTING + + addFormatToken('D', ['DD', 2], 'Do', 'date'); + + // ALIASES + + addUnitAlias('date', 'D'); + + // PRIORITY + addUnitPriority('date', 9); + + // PARSING + + addRegexToken('D', match1to2); + addRegexToken('DD', match1to2, match2); + addRegexToken('Do', function (isStrict, locale) { + // TODO: Remove "ordinalParse" fallback in next major release. + return isStrict ? + (locale._dayOfMonthOrdinalParse || locale._ordinalParse) : + locale._dayOfMonthOrdinalParseLenient; + }); + + addParseToken(['D', 'DD'], DATE); + addParseToken('Do', function (input, array) { + array[DATE] = toInt(input.match(match1to2)[0]); + }); + + // MOMENTS + + var getSetDayOfMonth = makeGetSet('Date', true); + + // FORMATTING + + addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); + + // ALIASES + + addUnitAlias('dayOfYear', 'DDD'); + + // PRIORITY + addUnitPriority('dayOfYear', 4); + + // PARSING + + addRegexToken('DDD', match1to3); + addRegexToken('DDDD', match3); + addParseToken(['DDD', 'DDDD'], function (input, array, config) { + config._dayOfYear = toInt(input); + }); + + // HELPERS + + // MOMENTS + + function getSetDayOfYear (input) { + var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; + return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); + } + + // FORMATTING + + addFormatToken('m', ['mm', 2], 0, 'minute'); + + // ALIASES + + addUnitAlias('minute', 'm'); + + // PRIORITY + + addUnitPriority('minute', 14); + + // PARSING + + addRegexToken('m', match1to2); + addRegexToken('mm', match1to2, match2); + addParseToken(['m', 'mm'], MINUTE); + + // MOMENTS + + var getSetMinute = makeGetSet('Minutes', false); + + // FORMATTING + + addFormatToken('s', ['ss', 2], 0, 'second'); + + // ALIASES + + addUnitAlias('second', 's'); + + // PRIORITY + + addUnitPriority('second', 15); + + // PARSING + + addRegexToken('s', match1to2); + addRegexToken('ss', match1to2, match2); + addParseToken(['s', 'ss'], SECOND); + + // MOMENTS + + var getSetSecond = makeGetSet('Seconds', false); + + // FORMATTING + + addFormatToken('S', 0, 0, function () { + return ~~(this.millisecond() / 100); + }); + + addFormatToken(0, ['SS', 2], 0, function () { + return ~~(this.millisecond() / 10); + }); + + addFormatToken(0, ['SSS', 3], 0, 'millisecond'); + addFormatToken(0, ['SSSS', 4], 0, function () { + return this.millisecond() * 10; + }); + addFormatToken(0, ['SSSSS', 5], 0, function () { + return this.millisecond() * 100; + }); + addFormatToken(0, ['SSSSSS', 6], 0, function () { + return this.millisecond() * 1000; + }); + addFormatToken(0, ['SSSSSSS', 7], 0, function () { + return this.millisecond() * 10000; + }); + addFormatToken(0, ['SSSSSSSS', 8], 0, function () { + return this.millisecond() * 100000; + }); + addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { + return this.millisecond() * 1000000; + }); + + + // ALIASES + + addUnitAlias('millisecond', 'ms'); + + // PRIORITY + + addUnitPriority('millisecond', 16); + + // PARSING + + addRegexToken('S', match1to3, match1); + addRegexToken('SS', match1to3, match2); + addRegexToken('SSS', match1to3, match3); + + var token; + for (token = 'SSSS'; token.length <= 9; token += 'S') { + addRegexToken(token, matchUnsigned); + } + + function parseMs(input, array) { + array[MILLISECOND] = toInt(('0.' + input) * 1000); + } + + for (token = 'S'; token.length <= 9; token += 'S') { + addParseToken(token, parseMs); + } + // MOMENTS + + var getSetMillisecond = makeGetSet('Milliseconds', false); + + // FORMATTING + + addFormatToken('z', 0, 0, 'zoneAbbr'); + addFormatToken('zz', 0, 0, 'zoneName'); + + // MOMENTS + + function getZoneAbbr () { + return this._isUTC ? 'UTC' : ''; + } + + function getZoneName () { + return this._isUTC ? 'Coordinated Universal Time' : ''; + } + + var proto = Moment.prototype; + + proto.add = add; + proto.calendar = calendar$1; + proto.clone = clone; + proto.diff = diff; + proto.endOf = endOf; + proto.format = format; + proto.from = from; + proto.fromNow = fromNow; + proto.to = to; + proto.toNow = toNow; + proto.get = stringGet; + proto.invalidAt = invalidAt; + proto.isAfter = isAfter; + proto.isBefore = isBefore; + proto.isBetween = isBetween; + proto.isSame = isSame; + proto.isSameOrAfter = isSameOrAfter; + proto.isSameOrBefore = isSameOrBefore; + proto.isValid = isValid$2; + proto.lang = lang; + proto.locale = locale; + proto.localeData = localeData; + proto.max = prototypeMax; + proto.min = prototypeMin; + proto.parsingFlags = parsingFlags; + proto.set = stringSet; + proto.startOf = startOf; + proto.subtract = subtract; + proto.toArray = toArray; + proto.toObject = toObject; + proto.toDate = toDate; + proto.toISOString = toISOString; + proto.inspect = inspect; + proto.toJSON = toJSON; + proto.toString = toString; + proto.unix = unix; + proto.valueOf = valueOf; + proto.creationData = creationData; + proto.year = getSetYear; + proto.isLeapYear = getIsLeapYear; + proto.weekYear = getSetWeekYear; + proto.isoWeekYear = getSetISOWeekYear; + proto.quarter = proto.quarters = getSetQuarter; + proto.month = getSetMonth; + proto.daysInMonth = getDaysInMonth; + proto.week = proto.weeks = getSetWeek; + proto.isoWeek = proto.isoWeeks = getSetISOWeek; + proto.weeksInYear = getWeeksInYear; + proto.isoWeeksInYear = getISOWeeksInYear; + proto.date = getSetDayOfMonth; + proto.day = proto.days = getSetDayOfWeek; + proto.weekday = getSetLocaleDayOfWeek; + proto.isoWeekday = getSetISODayOfWeek; + proto.dayOfYear = getSetDayOfYear; + proto.hour = proto.hours = getSetHour; + proto.minute = proto.minutes = getSetMinute; + proto.second = proto.seconds = getSetSecond; + proto.millisecond = proto.milliseconds = getSetMillisecond; + proto.utcOffset = getSetOffset; + proto.utc = setOffsetToUTC; + proto.local = setOffsetToLocal; + proto.parseZone = setOffsetToParsedOffset; + proto.hasAlignedHourOffset = hasAlignedHourOffset; + proto.isDST = isDaylightSavingTime; + proto.isLocal = isLocal; + proto.isUtcOffset = isUtcOffset; + proto.isUtc = isUtc; + proto.isUTC = isUtc; + proto.zoneAbbr = getZoneAbbr; + proto.zoneName = getZoneName; + proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); + proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); + proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); + proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); + proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); + + function createUnix (input) { + return createLocal(input * 1000); + } + + function createInZone () { + return createLocal.apply(null, arguments).parseZone(); + } + + function preParsePostFormat (string) { + return string; + } + + var proto$1 = Locale.prototype; + + proto$1.calendar = calendar; + proto$1.longDateFormat = longDateFormat; + proto$1.invalidDate = invalidDate; + proto$1.ordinal = ordinal; + proto$1.preparse = preParsePostFormat; + proto$1.postformat = preParsePostFormat; + proto$1.relativeTime = relativeTime; + proto$1.pastFuture = pastFuture; + proto$1.set = set; + + proto$1.months = localeMonths; + proto$1.monthsShort = localeMonthsShort; + proto$1.monthsParse = localeMonthsParse; + proto$1.monthsRegex = monthsRegex; + proto$1.monthsShortRegex = monthsShortRegex; + proto$1.week = localeWeek; + proto$1.firstDayOfYear = localeFirstDayOfYear; + proto$1.firstDayOfWeek = localeFirstDayOfWeek; + + proto$1.weekdays = localeWeekdays; + proto$1.weekdaysMin = localeWeekdaysMin; + proto$1.weekdaysShort = localeWeekdaysShort; + proto$1.weekdaysParse = localeWeekdaysParse; + + proto$1.weekdaysRegex = weekdaysRegex; + proto$1.weekdaysShortRegex = weekdaysShortRegex; + proto$1.weekdaysMinRegex = weekdaysMinRegex; + + proto$1.isPM = localeIsPM; + proto$1.meridiem = localeMeridiem; + + function get$1 (format, index, field, setter) { + var locale = getLocale(); + var utc = createUTC().set(setter, index); + return locale[field](utc, format); + } + + function listMonthsImpl (format, index, field) { + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + + if (index != null) { + return get$1(format, index, field, 'month'); + } + + var i; + var out = []; + for (i = 0; i < 12; i++) { + out[i] = get$1(format, i, field, 'month'); + } + return out; + } + + // () + // (5) + // (fmt, 5) + // (fmt) + // (true) + // (true, 5) + // (true, fmt, 5) + // (true, fmt) + function listWeekdaysImpl (localeSorted, format, index, field) { + if (typeof localeSorted === 'boolean') { + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + } else { + format = localeSorted; + index = format; + localeSorted = false; + + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + } + + var locale = getLocale(), + shift = localeSorted ? locale._week.dow : 0; + + if (index != null) { + return get$1(format, (index + shift) % 7, field, 'day'); + } + + var i; + var out = []; + for (i = 0; i < 7; i++) { + out[i] = get$1(format, (i + shift) % 7, field, 'day'); + } + return out; + } + + function listMonths (format, index) { + return listMonthsImpl(format, index, 'months'); + } + + function listMonthsShort (format, index) { + return listMonthsImpl(format, index, 'monthsShort'); + } + + function listWeekdays (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); + } + + function listWeekdaysShort (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); + } + + function listWeekdaysMin (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); + } + + getSetGlobalLocale('en', { + dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, + ordinal : function (number) { + var b = number % 10, + output = (toInt(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + } + }); + + // Side effect imports + + hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); + hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); + + var mathAbs = Math.abs; + + function abs () { + var data = this._data; + + this._milliseconds = mathAbs(this._milliseconds); + this._days = mathAbs(this._days); + this._months = mathAbs(this._months); + + data.milliseconds = mathAbs(data.milliseconds); + data.seconds = mathAbs(data.seconds); + data.minutes = mathAbs(data.minutes); + data.hours = mathAbs(data.hours); + data.months = mathAbs(data.months); + data.years = mathAbs(data.years); + + return this; + } + + function addSubtract$1 (duration, input, value, direction) { + var other = createDuration(input, value); + + duration._milliseconds += direction * other._milliseconds; + duration._days += direction * other._days; + duration._months += direction * other._months; + + return duration._bubble(); + } + + // supports only 2.0-style add(1, 's') or add(duration) + function add$1 (input, value) { + return addSubtract$1(this, input, value, 1); + } + + // supports only 2.0-style subtract(1, 's') or subtract(duration) + function subtract$1 (input, value) { + return addSubtract$1(this, input, value, -1); + } + + function absCeil (number) { + if (number < 0) { + return Math.floor(number); + } else { + return Math.ceil(number); + } + } + + function bubble () { + var milliseconds = this._milliseconds; + var days = this._days; + var months = this._months; + var data = this._data; + var seconds, minutes, hours, years, monthsFromDays; + + // if we have a mix of positive and negative values, bubble down first + // check: https://github.com/moment/moment/issues/2166 + if (!((milliseconds >= 0 && days >= 0 && months >= 0) || + (milliseconds <= 0 && days <= 0 && months <= 0))) { + milliseconds += absCeil(monthsToDays(months) + days) * 864e5; + days = 0; + months = 0; + } + + // The following code bubbles up values, see the tests for + // examples of what that means. + data.milliseconds = milliseconds % 1000; + + seconds = absFloor(milliseconds / 1000); + data.seconds = seconds % 60; + + minutes = absFloor(seconds / 60); + data.minutes = minutes % 60; + + hours = absFloor(minutes / 60); + data.hours = hours % 24; + + days += absFloor(hours / 24); + + // convert days to months + monthsFromDays = absFloor(daysToMonths(days)); + months += monthsFromDays; + days -= absCeil(monthsToDays(monthsFromDays)); + + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; + + data.days = days; + data.months = months; + data.years = years; + + return this; + } + + function daysToMonths (days) { + // 400 years have 146097 days (taking into account leap year rules) + // 400 years have 12 months === 4800 + return days * 4800 / 146097; + } + + function monthsToDays (months) { + // the reverse of daysToMonths + return months * 146097 / 4800; + } + + function as (units) { + if (!this.isValid()) { + return NaN; + } + var days; + var months; + var milliseconds = this._milliseconds; + + units = normalizeUnits(units); + + if (units === 'month' || units === 'year') { + days = this._days + milliseconds / 864e5; + months = this._months + daysToMonths(days); + return units === 'month' ? months : months / 12; + } else { + // handle milliseconds separately because of floating point math errors (issue #1867) + days = this._days + Math.round(monthsToDays(this._months)); + switch (units) { + case 'week' : return days / 7 + milliseconds / 6048e5; + case 'day' : return days + milliseconds / 864e5; + case 'hour' : return days * 24 + milliseconds / 36e5; + case 'minute' : return days * 1440 + milliseconds / 6e4; + case 'second' : return days * 86400 + milliseconds / 1000; + // Math.floor prevents floating point math errors here + case 'millisecond': return Math.floor(days * 864e5) + milliseconds; + default: throw new Error('Unknown unit ' + units); + } + } + } + + // TODO: Use this.as('ms')? + function valueOf$1 () { + if (!this.isValid()) { + return NaN; + } + return ( + this._milliseconds + + this._days * 864e5 + + (this._months % 12) * 2592e6 + + toInt(this._months / 12) * 31536e6 + ); + } + + function makeAs (alias) { + return function () { + return this.as(alias); + }; + } + + var asMilliseconds = makeAs('ms'); + var asSeconds = makeAs('s'); + var asMinutes = makeAs('m'); + var asHours = makeAs('h'); + var asDays = makeAs('d'); + var asWeeks = makeAs('w'); + var asMonths = makeAs('M'); + var asYears = makeAs('y'); + + function clone$1 () { + return createDuration(this); + } + + function get$2 (units) { + units = normalizeUnits(units); + return this.isValid() ? this[units + 's']() : NaN; + } + + function makeGetter(name) { + return function () { + return this.isValid() ? this._data[name] : NaN; + }; + } + + var milliseconds = makeGetter('milliseconds'); + var seconds = makeGetter('seconds'); + var minutes = makeGetter('minutes'); + var hours = makeGetter('hours'); + var days = makeGetter('days'); + var months = makeGetter('months'); + var years = makeGetter('years'); + + function weeks () { + return absFloor(this.days() / 7); + } + + var round = Math.round; + var thresholds = { + ss: 44, // a few seconds to seconds + s : 45, // seconds to minute + m : 45, // minutes to hour + h : 22, // hours to day + d : 26, // days to month + M : 11 // months to year + }; + + // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize + function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { + return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); + } + + function relativeTime$1 (posNegDuration, withoutSuffix, locale) { + var duration = createDuration(posNegDuration).abs(); + var seconds = round(duration.as('s')); + var minutes = round(duration.as('m')); + var hours = round(duration.as('h')); + var days = round(duration.as('d')); + var months = round(duration.as('M')); + var years = round(duration.as('y')); + + var a = seconds <= thresholds.ss && ['s', seconds] || + seconds < thresholds.s && ['ss', seconds] || + minutes <= 1 && ['m'] || + minutes < thresholds.m && ['mm', minutes] || + hours <= 1 && ['h'] || + hours < thresholds.h && ['hh', hours] || + days <= 1 && ['d'] || + days < thresholds.d && ['dd', days] || + months <= 1 && ['M'] || + months < thresholds.M && ['MM', months] || + years <= 1 && ['y'] || ['yy', years]; + + a[2] = withoutSuffix; + a[3] = +posNegDuration > 0; + a[4] = locale; + return substituteTimeAgo.apply(null, a); + } + + // This function allows you to set the rounding function for relative time strings + function getSetRelativeTimeRounding (roundingFunction) { + if (roundingFunction === undefined) { + return round; + } + if (typeof(roundingFunction) === 'function') { + round = roundingFunction; + return true; + } + return false; + } + + // This function allows you to set a threshold for relative time strings + function getSetRelativeTimeThreshold (threshold, limit) { + if (thresholds[threshold] === undefined) { + return false; + } + if (limit === undefined) { + return thresholds[threshold]; + } + thresholds[threshold] = limit; + if (threshold === 's') { + thresholds.ss = limit - 1; + } + return true; + } + + function humanize (withSuffix) { + if (!this.isValid()) { + return this.localeData().invalidDate(); + } + + var locale = this.localeData(); + var output = relativeTime$1(this, !withSuffix, locale); + + if (withSuffix) { + output = locale.pastFuture(+this, output); + } + + return locale.postformat(output); + } + + var abs$1 = Math.abs; + + function sign(x) { + return ((x > 0) - (x < 0)) || +x; + } + + function toISOString$1() { + // for ISO strings we do not use the normal bubbling rules: + // * milliseconds bubble up until they become hours + // * days do not bubble at all + // * months bubble up until they become years + // This is because there is no context-free conversion between hours and days + // (think of clock changes) + // and also not between days and months (28-31 days per month) + if (!this.isValid()) { + return this.localeData().invalidDate(); + } + + var seconds = abs$1(this._milliseconds) / 1000; + var days = abs$1(this._days); + var months = abs$1(this._months); + var minutes, hours, years; + + // 3600 seconds -> 60 minutes -> 1 hour + minutes = absFloor(seconds / 60); + hours = absFloor(minutes / 60); + seconds %= 60; + minutes %= 60; + + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; + + + // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js + var Y = years; + var M = months; + var D = days; + var h = hours; + var m = minutes; + var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; + var total = this.asSeconds(); + + if (!total) { + // this is the same as C#'s (Noda) and python (isodate)... + // but not other JS (goog.date) + return 'P0D'; + } + + var totalSign = total < 0 ? '-' : ''; + var ymSign = sign(this._months) !== sign(total) ? '-' : ''; + var daysSign = sign(this._days) !== sign(total) ? '-' : ''; + var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; + + return totalSign + 'P' + + (Y ? ymSign + Y + 'Y' : '') + + (M ? ymSign + M + 'M' : '') + + (D ? daysSign + D + 'D' : '') + + ((h || m || s) ? 'T' : '') + + (h ? hmsSign + h + 'H' : '') + + (m ? hmsSign + m + 'M' : '') + + (s ? hmsSign + s + 'S' : ''); + } + + var proto$2 = Duration.prototype; + + proto$2.isValid = isValid$1; + proto$2.abs = abs; + proto$2.add = add$1; + proto$2.subtract = subtract$1; + proto$2.as = as; + proto$2.asMilliseconds = asMilliseconds; + proto$2.asSeconds = asSeconds; + proto$2.asMinutes = asMinutes; + proto$2.asHours = asHours; + proto$2.asDays = asDays; + proto$2.asWeeks = asWeeks; + proto$2.asMonths = asMonths; + proto$2.asYears = asYears; + proto$2.valueOf = valueOf$1; + proto$2._bubble = bubble; + proto$2.clone = clone$1; + proto$2.get = get$2; + proto$2.milliseconds = milliseconds; + proto$2.seconds = seconds; + proto$2.minutes = minutes; + proto$2.hours = hours; + proto$2.days = days; + proto$2.weeks = weeks; + proto$2.months = months; + proto$2.years = years; + proto$2.humanize = humanize; + proto$2.toISOString = toISOString$1; + proto$2.toString = toISOString$1; + proto$2.toJSON = toISOString$1; + proto$2.locale = locale; + proto$2.localeData = localeData; + + proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1); + proto$2.lang = lang; + + // Side effect imports + + // FORMATTING + + addFormatToken('X', 0, 0, 'unix'); + addFormatToken('x', 0, 0, 'valueOf'); + + // PARSING + + addRegexToken('x', matchSigned); + addRegexToken('X', matchTimestamp); + addParseToken('X', function (input, array, config) { + config._d = new Date(parseFloat(input, 10) * 1000); + }); + addParseToken('x', function (input, array, config) { + config._d = new Date(toInt(input)); + }); + + // Side effect imports + + + hooks.version = '2.23.0'; + + setHookCallback(createLocal); + + hooks.fn = proto; + hooks.min = min; + hooks.max = max; + hooks.now = now; + hooks.utc = createUTC; + hooks.unix = createUnix; + hooks.months = listMonths; + hooks.isDate = isDate; + hooks.locale = getSetGlobalLocale; + hooks.invalid = createInvalid; + hooks.duration = createDuration; + hooks.isMoment = isMoment; + hooks.weekdays = listWeekdays; + hooks.parseZone = createInZone; + hooks.localeData = getLocale; + hooks.isDuration = isDuration; + hooks.monthsShort = listMonthsShort; + hooks.weekdaysMin = listWeekdaysMin; + hooks.defineLocale = defineLocale; + hooks.updateLocale = updateLocale; + hooks.locales = listLocales; + hooks.weekdaysShort = listWeekdaysShort; + hooks.normalizeUnits = normalizeUnits; + hooks.relativeTimeRounding = getSetRelativeTimeRounding; + hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; + hooks.calendarFormat = getCalendarFormat; + hooks.prototype = proto; + + // currently HTML5 input type only supports 24-hour formats + hooks.HTML5_FMT = { + DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // + DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // + DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // + DATE: 'YYYY-MM-DD', // + TIME: 'HH:mm', // + TIME_SECONDS: 'HH:mm:ss', // + TIME_MS: 'HH:mm:ss.SSS', // + WEEK: 'GGGG-[W]WW', // + MONTH: 'YYYY-MM' // + }; + + return hooks; + +}))); diff --git a/plugins/calendar/print.js b/plugins/calendar/print.js index 6b7c584c..fde81486 100644 --- a/plugins/calendar/print.js +++ b/plugins/calendar/print.js @@ -37,12 +37,13 @@ window.rcmail && rcmail.addEventListener('init', function(evt) { var rc_loading; var showdesc = true; + var desc_elements = {}; var settings = $.extend(rcmail.env.calendar_settings, rcmail.env.libcal_settings); // create list of event sources AKA calendars - var src, event_sources = []; - var add_url = (rcmail.env.search ? '&q='+escape(rcmail.env.search) : ''); - for (var id in rcmail.env.calendars) { + var id, src, event_sources = []; + var add_url = '&mode=print' + (rcmail.env.search ? '&q='+escape(rcmail.env.search) : ''); + for (id in rcmail.env.calendars) { if (!rcmail.env.calendars[id].active) continue; @@ -54,6 +55,9 @@ window.rcmail && rcmail.addEventListener('init', function(evt) { source.color = '#' + source.color.replace(/^#/, ''); + if (source.color == '#ffffff') + source.color = '#ccc'; + event_sources.push(source); } @@ -66,72 +70,89 @@ window.rcmail && rcmail.addEventListener('init', function(evt) { header: { left: '', center: 'title', - right: 'agendaDay,agendaWeek,month,table' + right: 'agendaDay,agendaWeek,month,list' }, + theme: false, aspectRatio: 0.85, - ignoreTimezone: true, // will treat the given date strings as in local (browser's) timezone - date: viewdate.getDate(), - month: viewdate.getMonth(), - year: viewdate.getFullYear(), + selectable: false, + editable: false, + timezone: false, // will treat the given date strings as in local (browser's) timezone + monthNames: settings.months, + monthNamesShort: settings.months_short, + dayNames: settings.days, + dayNamesShort: settings.days_short, + weekNumbers: settings.show_weekno > 0, + weekNumberTitle: rcmail.gettext('weekshort', 'calendar') + ' ', + firstDay: settings.first_day, + firstHour: settings.first_hour, + slotDuration: {minutes: 60/settings.timeslots}, + businessHours: { + start: settings.work_start + ':00', + end: settings.work_end + ':00' + }, + views: { + list: { + titleFormat: settings.dates_long, + listDayFormat: settings.date_long, + visibleRange: function(currentDate) { + return { + start: currentDate.clone(), + end: currentDate.clone().add(settings.agenda_range, 'days') + } + } + }, + month: { + columnFormat: 'ddd', // Mon + titleFormat: 'MMMM YYYY', + eventLimit: 10 + }, + week: { + columnFormat: 'ddd ' + settings.date_short, // Mon 9/7 + titleFormat: settings.dates_long + }, + day: { + columnFormat: 'dddd ' + settings.date_short, // Monday 9/7 + titleFormat: 'dddd ' + settings.date_long + } + }, + timeFormat: settings.time_format, + slotLabelFormat: settings.time_format, + allDayText: rcmail.gettext('all-day', 'calendar'), + defaultDate: viewdate, defaultView: rcmail.env.view, eventSources: event_sources, - monthNames : settings['months'], - monthNamesShort : settings['months_short'], - dayNames : settings['days'], - dayNamesShort : settings['days_short'], - firstDay : settings['first_day'], - firstHour : settings['first_hour'], - slotMinutes : 60/settings['timeslots'], - timeFormat: { - '': settings['time_format'], - agenda: settings['time_format'] + '{ - ' + settings['time_format'] + '}', - list: settings['time_format'] + '{ - ' + settings['time_format'] + '}', - table: settings['time_format'] + '{ - ' + settings['time_format'] + '}' - }, - axisFormat : settings['time_format'], - columnFormat: { - month: 'ddd', // Mon - week: 'ddd ' + settings['date_short'], // Mon 9/7 - day: 'dddd ' + settings['date_short'], // Monday 9/7 - list: settings['date_agenda'], - table: settings['date_agenda'] - }, - titleFormat: { - month: 'MMMM yyyy', - week: settings['dates_long'], - day: 'dddd ' + settings['date_long'], - list: settings['dates_long'], - table: settings['dates_long'] - }, - listSections: rcmail.env.listSections !== undefined ? rcmail.env.listSections : settings['agenda_sections'], - listRange: rcmail.env.listRange || settings['agenda_range'], - tableCols: ['handle', 'date', 'time', 'title', 'location'], - allDayText: rcmail.gettext('all-day', 'calendar'), buttonText: { + today: settings['today'], day: rcmail.gettext('day', 'calendar'), week: rcmail.gettext('week', 'calendar'), month: rcmail.gettext('month', 'calendar'), - table: rcmail.gettext('agenda', 'calendar') + list: rcmail.gettext('agenda', 'calendar') }, - listTexts: { - until: rcmail.gettext('until', 'calendar'), - past: rcmail.gettext('pastevents', 'calendar'), - today: rcmail.gettext('today', 'calendar'), - tomorrow: rcmail.gettext('tomorrow', 'calendar'), - thisWeek: rcmail.gettext('thisweek', 'calendar'), - nextWeek: rcmail.gettext('nextweek', 'calendar'), - thisMonth: rcmail.gettext('thismonth', 'calendar'), - nextMonth: rcmail.gettext('nextmonth', 'calendar'), - future: rcmail.gettext('futureevents', 'calendar'), - week: rcmail.gettext('weekofyear', 'calendar') + buttonIcons: { + prev: 'left-single-arrow', + next: 'right-single-arrow' + }, + eventLimitText: function(num) { + return rcmail.gettext('andnmore', 'calendar').replace('$nr', num); }, loading: function(isLoading) { rc_loading = rcmail.set_busy(isLoading, 'loading', rc_loading); }, // event rendering eventRender: function(event, element, view) { - if (view.name != 'month' && view.name != 'table') { - var cont = element.find('.fc-event-title'); + if (view.name == 'list') { + var loc = $('').attr('class', 'fc-event-location'); + if (event.location) + loc.text(event.location); + element.find('.fc-list-item-title').after(loc); + + // we can't add HTML elements after the curent element, + // so we store it for later. One description per event + if (event.description && showdesc && !desc_elements[event.uid]) + desc_elements[event.uid] = {element: element[0], description: event.description}; + } + else if (view.name != 'month') { + var cont = element.find('div.fc-title'); if (event.location) { cont.after('
    @ ' + Q(event.location) + '
    '); cont = cont.next(); @@ -139,47 +160,35 @@ window.rcmail && rcmail.addEventListener('init', function(evt) { if (event.description && showdesc) { cont.after('
    ' + Q(event.description) + '
    '); } -/* TODO: create icons black on white - if (event.recurrence) - element.find('.fc-event-time').append(''); - if (event.alarms) - element.find('.fc-event-time').append(''); -*/ - } - if (view.name == 'table' && event.description && showdesc) { - var cols = element.children().css('border', 0).length; - element.after('' + Q(event.description) + ''); } }, - viewDisplay: function(view) { - // remove hard-coded hight and make contents visible - window.setTimeout(function(){ - if (view.name == 'table') { - $('div.fc-list-content').css('overflow', 'visible').height('auto'); - } - else { - $('div.fc-agenda-divider') - .next().css('overflow', 'visible').height('auto') - .children('div').css('overflow', 'visible').height('auto'); - } - // adjust fixed height if vertical day slots - var h = $('table.fc-agenda-slots:visible').height() + $('table.fc-agenda-allday:visible').height() + 4; - if (h) $('table.fc-agenda-days td.fc-widget-content').children('div').height(h); - }, 20); + eventAfterAllRender: function(view) { + if (view.name == 'list') { + // Fix colspan of headers after we added Location column + fc.find('tr.fc-list-heading > td').attr('colspan', 4); + + $.each(desc_elements, function() { + $(this.element).after('' + Q(this.description) + ''); + }); + } + }, + viewRender: function(view) { + desc_elements = {}; } }); // activate settings form - $('#propdescription').change(function(){ + $('#propdescription').change(function() { showdesc = this.checked; - fc.fullCalendar('render'); + desc_elements = {}; + fc.fullCalendar('rerenderEvents'); }); var selector = $('#calendar').data('view-selector'); if (selector) { selector = $('#' + selector); - $('.fc-header-right > span').each(function() { + $('.fc-right button').each(function() { var cl = 'btn btn-secondary', btn = $(this); if (btn.is('.fc-state-active')) { diff --git a/plugins/calendar/skins/larry/calendar.css b/plugins/calendar/skins/larry/calendar.css index 3a88258f..4df834ea 100644 --- a/plugins/calendar/skins/larry/calendar.css +++ b/plugins/calendar/skins/larry/calendar.css @@ -1581,12 +1581,9 @@ a.dropdown-link:after { bottom: -1px; } -#resource-freebusy-calendar .fc-content { - top: 0; -} - -#resource-freebusy-calendar .fc-content .fc-event-bg { - background: 0; +#resource-freebusy-calendar .fc-toolbar { + height: 0; + margin: 0; } #resource-freebusy-calendar .fc-event.status-busy, @@ -1615,8 +1612,7 @@ a.dropdown-link:after { #resourcesearchbox { width: 100%; height: 26px; - -moz-box-sizing: border-box; - box-sizing: border-box; + box-sizing: border-box; } #resourcequicksearch .iconbutton.searchoptions { @@ -1633,33 +1629,22 @@ a.dropdown-link:after { } - /* fullcalendar style overrides */ -.rcube-fc-content { - overflow: hidden; - border: 0; - border-radius: 4px; -} - -.calendarmain .fc-content { - position: absolute !important; - top: 40px; - left: 0; - right: 0; - bottom: 0; +.calendarmain .fc-body, +.fc-scroller { background: #fff; } -.calendarmain.quickview-active .fc-content { +.calendarmain.quickview-active .fc-view .fc-scroller { background-image: url('images/focusview.png'); background-position: center; background-repeat: no-repeat; } -#fish-eye-view .fc-content { - top: 2px; - bottom: 2px; +.fc-unthemed .fc-list-heading td { + background: rgba(0, 0, 0, .05); + padding: 8px; } #quickview-calendar { @@ -1676,9 +1661,9 @@ a.dropdown-link:after { .calendarmain #calendar .fc-button, .calendarmain #calendar .fc-button.fc-state-default, .calendarmain #calendar .fc-button.fc-state-hover { - margin: -2px 0 0 0; - height: 24px; - line-height: 24px; + margin-top: -2px; + height: 26px; + line-height: 26px; color: #333; border: 1px solid #ababab; background: #f1f1f1; @@ -1704,15 +1689,12 @@ a.dropdown-link:after { margin-right: 0; } -.calendarmain #calendar .fc-header-left .fc-button { - display: inline-block; - margin: 0; - text-align: center; +.calendarmain #calendar .fc-left .fc-button { font-size: 10px; color: #555; min-width: 50px; max-width: 75px; - height: 13px; + height: 40px; line-height: 1em; overflow: hidden; text-overflow: ellipsis; @@ -1723,89 +1705,91 @@ a.dropdown-link:after { border: 0; background: url(images/toolbar.png) center 100px no-repeat; box-shadow: none; - -o-box-shadow: none; - -webkit-box-shadow: none; - -moz-box-shadow: none; outline: none; + transition: none; } -.calendarmain #calendar .fc-header-left .fc-button:focus { +.calendarmain #calendar .fc-left .fc-button:focus { color: #fff; text-shadow: 0px 1px 1px #666; background-color: rgba(30,150,192, 0.5); border-radius: 3px; } -.calendarmain #calendar .fc-header-left .fc-button.fc-state-active { +.calendarmain #calendar .fc-left .fc-button::-moz-focus-inner { + border: 0; +} + +.calendarmain #calendar .fc-left .fc-button.fc-state-active { font-weight: bold; color: #222; text-shadow: none; background-color: transparent; } -.calendarmain #calendar .fc-header-left .fc-button-agendaDay { +.calendarmain #calendar .fc-left .fc-agendaDay-button { background-position: center -120px; } -.calendarmain #calendar .fc-header-left .fc-button-agendaDay.fc-state-active { +.calendarmain #calendar .fc-left .fc-agendaDay-button.fc-state-active { background-position: center -160px; } -.calendarmain #calendar .fc-header-left .fc-button-agendaWeek { +.calendarmain #calendar .fc-left .fc-agendaWeek-button { background-position: center -200px; } -.calendarmain #calendar .fc-header-left .fc-button-agendaWeek.fc-state-active { +.calendarmain #calendar .fc-left .fc-agendaWeek-button.fc-state-active { background-position: center -240px; } -.calendarmain #calendar .fc-header-left .fc-button-month { +.calendarmain #calendar .fc-left .fc-month-button { background-position: center -280px; } -.calendarmain #calendar .fc-header-left .fc-button-month.fc-state-active { +.calendarmain #calendar .fc-left .fc-month-button.fc-state-active { background-position: center -320px; } -.calendarmain #calendar .fc-header-left .fc-button-table { +.calendarmain #calendar .fc-left .fc-list-button { background-position: center -360px; } -.calendarmain #calendar .fc-header-left .fc-button-table.fc-state-active { +.calendarmain #calendar .fc-left .fc-list-button.fc-state-active { background-position: center -400px; } -.calendarmain #calendar .fc-header-right { - padding-right: 252px; +.calendarmain #calendar .fc-header-toolbar .fc-right { padding-top: 4px; } +.calendarmain #calendar .fc-header-toolbar .fc-center { + line-height: 2.5em; + overflow: hidden; + text-align: center; + display: block; +} + +.calendarmain #calendar .fc-header-toolbar .fc-center h2 { + float: none; +} + .calendarmain #calendar .fc-header-title { padding-top: 5px; } +.calendarmain #calendar .fc-toolbar.fc-header-toolbar { + margin-bottom: 7px; + margin-right: 250px; +} + .fc-event { font-size: 1em !important; } -.fc-event-hori.fc-type-freebusy, -.fc-event-vert.fc-type-freebusy { +.fc-event.fc-type-freebusy, +.fc-event.fc-type-freebusy { opacity: 0.60; -/* - color: #fff !important; - background: rgba(80,80,80,0.85) !important; - background: -moz-linear-gradient(top, rgba(80,80,80,0.85) 0%, rgba(48,48,48,0.9) 100%) !important; - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(80,80,80,0.85)), color-stop(100%,rgba(48,48,48,0.9))) !important; - background: -webkit-linear-gradient(top, rgba(80,80,80,0.85) 0%, rgba(48,48,48,0.85) 100%) !important; - background: -o-linear-gradient(top, rgba(80,80,80,0.85) 0%, rgba(48,48,48,0.85) 100%) !important; - background: -ms-linear-gradient(top, rgba(80,80,80,0.85) 0%, rgba(48,48,48,0.85) 100%) !important; - background: linear-gradient(to bottom, rgba(80,80,80,0.85) 0%, rgba(48,48,48,0.85) 100%) !important; - border-color: #444 !important; - cursor: default !important; -*/ - -moz-box-shadow: inset 0px 1px 0 0px #888; - -webkit-box-shadow: inset 0px 1px 0 0px #888; - -o-box-shadow: inset 0px 1px 0 0px #888; box-shadow: inset 0px 1px 0 0px #888; } @@ -1813,93 +1797,88 @@ a.dropdown-link:after { color: #999; } -.fc-event-hori.fc-type-freebusy .fc-event-skin, -.fc-event-hori.fc-type-freebusy .fc-event-inner, -.fc-event-vert.fc-type-freebusy .fc-event-skin, -.fc-event-vert.fc-type-freebusy .fc-event-inner { -/* - background-color: transparent !important; - border-color: #444 !important; - color: #fff !important; - text-shadow: 0 1px 1px #000; -*/ -} - -.fc-event-hori.fc-type-freebusy .fc-event-title, -.fc-event-vert.fc-type-freebusy .fc-event-title { +.fc-event.fc-type-freebusy .fc-title, +.fc-event.fc-type-freebusy .fc-title { position: absolute; top: -5000px; } -.fc-event-vert.fc-invitation-needs-action, -.fc-event-hori.fc-invitation-needs-action { +.fc-event.fc-invitation-needs-action, +.fc-event.fc-invitation-needs-action { border: 1px dashed #5757c7 !important; } -.fc-event-vert.fc-invitation-tentative, -.fc-event-hori.fc-invitation-tentative { +.fc-event.fc-invitation-tentative, +.fc-event.fc-invitation-tentative { border: 1px dashed #eb8900 !important; } -.fc-event-vert.fc-invitation-declined, -.fc-event-hori.fc-invitation-declined { +.fc-event.fc-invitation-declined, +.fc-event.fc-invitation-declined { border: 1px dashed #c00 !important; } -.fc-event-vert.fc-event-ns-other.fc-invitation-declined, -.fc-event-hori.fc-event-ns-other.fc-invitation-declined { +.fc-event.fc-event-ns-other.fc-invitation-declined, +.fc-event.fc-event-ns-other.fc-invitation-declined { opacity: 0.7; } -.fc-event-ns-other.fc-invitation-declined .fc-event-title { +.fc-event-ns-other.fc-invitation-declined .fc-title { text-decoration: line-through; } -.fc-event-vert.fc-invitation-tentative .fc-event-head, -.fc-event-vert.fc-invitation-declined .fc-event-head, -.fc-event-vert.fc-invitation-needs-action .fc-event-head { -/* background-color: transparent !important; */ +.fc-event .fc-bg { + opacity: 1; + background: unset; + margin-top: 14px; + cursor: pointer; } -.fc-event-vert.fc-invitation-tentative .fc-event-bg { +.fc-event.fc-invitation-tentative .fc-bg { background: url(data:image/gif;base64,R0lGODlhCAAIAPABAOuJAP///yH/C1hNUCBEYXRhWE1QAT8AIfkEBQAAAQAsAAAAAAgACAAAAg4Egmipx+ZaDPCtVPFNBQA7) 0 0 repeat #fff; + opacity: .25; } -.fc-event-vert.fc-invitation-needs-action .fc-event-bg { +.fc-event.fc-invitation-needs-action .fc-bg { background: url(data:image/gif;base64,R0lGODlhCAAIAPABAFdXx////yH/C1hNUCBEYXRhWE1QAT8AIfkEBQAAAQAsAAAAAAgACAAAAg4Egmipx+ZaDPCtVPFNBQA7) 0 0 repeat #fff; + opacity: .25; } -.fc-event-vert.fc-invitation-declined .fc-event-bg { +.fc-event.fc-invitation-declined .fc-bg { background: url(data:image/gif;base64,R0lGODlhCAAIAPABAMwAAP///yH/C1hNUCBEYXRhWE1QAT8AIfkEBQAAAQAsAAAAAAgACAAAAg4Egmipx+ZaDPCtVPFNBQA7) 0 0 repeat #fff; + opacity: .25; } -.fc-view-table tr.fc-invitation-tentative td, -.fc-view-table tr.fc-invitation-declined td, -.fc-view-table tr.fc-invitation-needs-action td { +.fc-list-view { + border-bottom: 0; +} + +.fc-title, +.fc-list-item-title { + font-weight: bold; +} + +.fc-list-table tr.fc-invitation-tentative td, +.fc-list-table tr.fc-invitation-declined td, +.fc-list-table tr.fc-invitation-needs-action td { color: #888; } -.fc-view-table tr.fc-invitation-tentative td.fc-event-title, -.fc-view-table tr.fc-invitation-declined td.fc-event-title, -.fc-view-table tr.fc-invitation-needs-action td.fc-event-title { +.fc-list-table tr.fc-invitation-tentative td.fc-list-item-title, +.fc-list-table tr.fc-invitation-declined td.fc-list-item-title, +.fc-list-table tr.fc-invitation-needs-action td.fc-list-item-title { font-weight: normal; } -#quickview-calendar .fc-view-table tr.fc-invitation-tentative td, -#quickview-calendar .fc-view-table tr.fc-invitation-declined td, -#quickview-calendar .fc-view-table tr.fc-invitation-needs-action td { +#quickview-calendar .fc-list-table tr.fc-invitation-tentative td, +#quickview-calendar .fc-list-table tr.fc-invitation-declined td, +#quickview-calendar .fc-list-table tr.fc-invitation-needs-action td { color: #333; } .calendarmain .fc-event:focus { outline: 1px solid rgba(71,135,177, 0.4); - -webkit-box-shadow: 0 0 2px 3px rgba(71,135,177, 0.6); - -moz-box-shadow: 0 0 2px 3px rgba(71,135,177, 0.6); - -o-box-shadow: 0 0 2px 3px rgba(71,135,177, 0.6); - box-shadow: 0 0 2px 3px rgba(71,135,177, 0.6); -} -.fc-event-title { - font-weight: bold; + box-shadow: 0 0 2px 3px rgba(71,135,177, 0.6); } .fc-needs-action, @@ -1908,40 +1887,40 @@ a.dropdown-link:after { opacity: 0.6; } -.cal-event-status-cancelled .fc-event-title { +.cal-event-status-cancelled .fc-title { text-decoration: line-through; } -.fc-event-hori .fc-event-title { +.fc-event-hori .fc-title { font-weight: normal; white-space: nowrap; } -.fc-event-hori .fc-event-time { +.fc-event-hori .fc-time { white-space: nowrap; font-weight: normal !important; font-size: 10px; padding-right: 0.6em; } -.fc-grid .fc-event-time { +.fc-grid .fc-time { font-weight: normal !important; padding-right: 0.3em; } -.calendarmain .fc-event-vert .fc-event-inner { +.calendarmain .fc-event .fc-inner { z-index: 0; } -.fc-event-cateories { - font-style:italic; +.fc-event-categories { + font-style: italic; } -div.fc-event-location { +.fc-event-location { font-size: 90%; } -.fc-more-link { +.fc-more { color: #999; padding-top: 1px; cursor: pointer; @@ -1955,13 +1934,13 @@ div.fc-event-location { background-color: rgba(198,198,198, 0.08); } -.calendarmain .fc-state-highlight { +.calendarmain .fc-unthemed td.fc-day.fc-today { background-color: rgba(233,198,14, 0.12); } .fc-widget-header, .fc-widget-content { - border-color: #bbd3da !important; + border-color: #c3c3c3 !important; } .fc-widget-header .fc-agenda-divider-inner { @@ -1974,6 +1953,11 @@ div.fc-event-location { text-shadow: 0px 1px 1px #fff; } +.fc-popover .fc-header .fc-title, +.fc-list-heading .fc-widget-header { + color: #666; +} + .fc-view thead th.fc-widget-header { padding: 8px 0; color: #69939e; @@ -2006,25 +1990,34 @@ div.fc-event-location { cursor: pointer; } -.calendarmain .fc-view-table td.fc-list-header { +.fc-list-table td.fc-list-header { color: #004458; font-size: 12px; } -.calendarmain .fc-view-table tr.fc-event td { - border-color: #bbd3da; +.fc-list-table tr.fc-list-item { + background: transparent; +} + +.fc-list-table tr.fc-list-item:hover td { + background: transparent; + cursor: pointer; +} + +.fc-list-table tr.fc-list-item td { + border-color: #c3c3c3; padding: 6px 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } -.calendarmain .fc-view-table tr.fc-event td.fc-event-handle { +.fc-list-table tr.fc-list-item td.fc-event-handle { padding: 6px 0 2px 7px; width: 12px; } -.calendarmain .fc-view-table .fc-event-handle .fc-event-skin { +.fc-list-table .fc-event-handle .fc-event-skin { margin: 0; padding: 0; display: inline-block; @@ -2034,7 +2027,7 @@ div.fc-event-location { border-radius: 8px; } -.calendarmain .fc-view-table .fc-event-handle .fc-event-inner { +.fc-list-table .fc-event-handle .fc-event-inner { display: inline-block; width: 10px; height: 10px; @@ -2045,35 +2038,44 @@ div.fc-event-location { border: 1px solid rgba(0, 0, 0, 0.4); } -.calendarmain .fc-view-table col.fc-event-location { +.calendarmain .fc-list-table col.fc-event-location { width: 25%; } -.fc-view-table table.fc-list-smart { -/* table-layout: auto; */ +.fc-event-dot { + vertical-align: middle; } -.fc-listappend { - text-align: center; - margin: 1em 0; -} - -.fc-listappend .message { - padding: 0.5em; - margin-bottom: 0.5em; +.fc-list-empty { font-size: 150%; color: #999; -} - -.fc-listappend .formlinks a { - font-size: 12px; - padding: 0 0.3em; - max-width: initial; + background: unset !important; } .fc-event-temp { opacity: 0.4; - filter: alpha(opacity=40); /* IE8 */ +} + +.fc-axis { + width: 35px !important; + padding: 0 3px !important; +} + +.fc .fc-week-number { + text-align: center; +} + +.fc-month-view .fc-week-number { + width: 20px !important; + padding: 2px 0; +} + +.fc-time-grid .fc-now-indicator { + border: 1px solid #3ec400; +} + +.fc-list-empty { + display: none; } /* Settings section */ diff --git a/plugins/calendar/skins/larry/fullcalendar.css b/plugins/calendar/skins/larry/fullcalendar.css index 80a47734..dcbc9997 100644 --- a/plugins/calendar/skins/larry/fullcalendar.css +++ b/plugins/calendar/skins/larry/fullcalendar.css @@ -1,711 +1,1293 @@ /*! - * FullCalendar v1.6.4-rcube-1.0 Stylesheet - * Docs & License: http://arshaw.com/fullcalendar/ - * (c) 2013 Adam Shaw, 2014 Kolab Systems AG + * FullCalendar v3.9.0 + * Docs & License: https://fullcalendar.io/ + * (c) 2018 Adam Shaw */ - - .fc { - direction: ltr; - text-align: left; - } - -.fc table { - border-collapse: collapse; - border-spacing: 0; - } - -html .fc, -.fc table { - font-size: 1em; - } - -.fc td, -.fc th { - padding: 0; - vertical-align: top; - } + direction: ltr; + text-align: left; } +.fc-rtl { + text-align: right; } +body .fc { + /* extra precedence to overcome jqui */ + font-size: 1em; } -/* Header -------------------------------------------------------------------------*/ +/* Colors +--------------------------------------------------------------------------------------------------*/ +.fc-highlight { + /* when user is selecting cells */ + background: #bce8f1; + opacity: .3; } -.fc-header td { - white-space: nowrap; - } +.fc-bgevent { + /* default look for background events */ + background: #8fdf82; + opacity: .3; } -.fc-header-left { - width: 25%; - text-align: left; - } - -.fc-header-center { - text-align: center; - } - -.fc-header-right { - width: 25%; - text-align: right; - } - -.fc-header-title { - display: inline-block; - vertical-align: top; - } - -.fc-header-title h2 { - margin-top: 0; - white-space: nowrap; - } - -.fc .fc-header-space { - padding-left: 10px; - } - -.fc-header .fc-button { - margin-bottom: 1em; - vertical-align: top; - } - -/* buttons edges butting together */ +.fc-nonbusiness { + /* default look for non-business-hours areas */ + /* will inherit .fc-bgevent's styles */ + background: #d7d7d7; } -.fc-header .fc-button { - margin-right: -1px; - } - -.fc-header .fc-corner-right, /* non-theme */ -.fc-header .ui-corner-right { /* theme */ - margin-right: 0; /* back to normal */ - } - -/* button layering (for border precedence) */ - -.fc-header .fc-state-hover, -.fc-header .ui-state-hover { - z-index: 2; - } - -.fc-header .fc-state-down { - z-index: 3; - } +/* Buttons (styled
    -').html(rcmail.gettext('andnmore', 'calendar').replace('$nr', event.attendees.length - j - 1)); + if (j == 7 && num_attendees > 8) { + morelink = $('').html(rcmail.gettext('andnmore', 'calendar').replace('$nr', num_attendees - j - 1)); } } - if (html && (event.attendees.length > 1 || !organizer)) { + if (html && (num_attendees > 1 || !organizer)) { $('#event-attendees').show() .find('.event-text') .html(html) From 6cd46fedcf1df3043d588c38e538945a41c94739 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Tue, 5 Feb 2019 10:56:12 +0100 Subject: [PATCH 22/98] Fix so calendar name in event view is not colored (Bifrost#T97743) It could be white making the text invisible. --- plugins/calendar/calendar_ui.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js index f930bcc7..bb90d7a7 100644 --- a/plugins/calendar/calendar_ui.js +++ b/plugins/calendar/calendar_ui.js @@ -359,14 +359,14 @@ function rcube_calendar_ui(settings) $('#event-alarm').show().find('.event-text').html(Q(event.alarms_text).replace(',', ',
    ')); if (calendar.name) - $('#event-calendar').show().find('.event-text').html(Q(calendar.name)).addClass('cal-'+calendar.id).css('color', calendar.textColor || calendar.color || ''); + $('#event-calendar').show().find('.event-text').text(calendar.name).addClass('cal-'+calendar.id); if (event.categories) - $('#event-category').show().find('.event-text').html(Q(event.categories)).addClass('cat-'+String(event.categories).toLowerCase().replace(rcmail.identifier_expr, '')); + $('#event-category').show().find('.event-text').text(event.categories).addClass('cat-'+String(event.categories).toLowerCase().replace(rcmail.identifier_expr, '')); if (event.free_busy) $('#event-free-busy').show().find('.event-text').text(rcmail.gettext(event.free_busy, 'calendar')); if (event.priority > 0) { var priolabels = [ '', rcmail.gettext('highest'), rcmail.gettext('high'), '', '', rcmail.gettext('normal'), '', '', rcmail.gettext('low'), rcmail.gettext('lowest') ]; - $('#event-priority').show().find('.event-text').html(Q(event.priority+' '+priolabels[event.priority])); + $('#event-priority').show().find('.event-text').text(event.priority+' '+priolabels[event.priority]); } if (event.status) { From 11ff8f71eaa7b59af817887dcc3d856baa8f8b06 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Wed, 6 Feb 2019 09:45:58 +0100 Subject: [PATCH 23/98] Fix various calendar regressions --- plugins/calendar/calendar.php | 3 - plugins/calendar/calendar_ui.js | 93 ++++++++++++------- plugins/calendar/lib/calendar_ui.php | 66 ++++--------- plugins/calendar/print.js | 2 +- .../skins/elastic/templates/calendar.html | 6 +- plugins/calendar/skins/larry/calendar.css | 9 +- plugins/libcalendaring/libcalendaring.js | 28 ++++++ .../skins/elastic/include/calendar.less | 30 +++++- 8 files changed, 143 insertions(+), 94 deletions(-) diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index afb23854..1a03fd34 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -1898,9 +1898,6 @@ class calendar extends rcube_plugin unset($event['allday']); $event['className'] = $event['className'] ? explode(' ', $event['className']) : array(); - if ($addcss) { - $event['className'][] = 'fc-event-cal-' . asciiwords($event['calendar'], true); - } if ($event['allDay']) { $event['end'] = $event['end']->add(new DateInterval('P1D')); diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js index bb90d7a7..e7a2fee6 100644 --- a/plugins/calendar/calendar_ui.js +++ b/plugins/calendar/calendar_ui.js @@ -162,6 +162,7 @@ function rcube_calendar_ui(settings) element.addClass('cal-event-status-' + String(event.status).toLowerCase()); } + set_event_colors(element, event, view.name); element.attr('aria-label', event.title + ', ' + me.event_date_text(event, true)); }, // callback when a specific event is clicked @@ -283,6 +284,50 @@ function rcube_calendar_ui(settings) return date.getHours() >= settings['work_start'] && date.getHours() < settings['work_end']; }; + var set_event_colors = function(element, event, mode) + { + var bg_color = '', border_color = '', + cat = String(event.categories), + color = event.calendar && me.calendars[event.calendar] ? me.calendars[event.calendar].color : '', + cat_color = rcmail.env.calendar_categories[cat] ? rcmail.env.calendar_categories[cat] : color; + + switch (settings.event_coloring) { + case 1: + bg_color = border_color = cat_color; + break; + case 2: + border_color = color; + bg_color = cat_color; + break; + case 3: + border_color = cat_color; + bg_color = color; + break; + default: + bg_color = border_color = color; + break; + } + + var css = { + 'border-color': border_color, + 'background-color': bg_color, + 'color': me.text_color(bg_color) + }; + + if (String(css['border-color']).match(/^#?f+$/i)) + delete css['border-color']; + + $.each(css, function(i, v) { if (!v) delete css[i]; if (v.charAt(0) != '#') css[i] = '#' + v; }); + + if (mode == 'list') { + bg_color = css['background-color']; + if (bg_color && !bg_color.match(/^#?f+$/i)) + $(element).find('.fc-event-dot').css('background-color', bg_color); + } + else + $(element).css(css); + }; + var load_attachment = function(data) { var event = data.record, @@ -340,24 +385,17 @@ function rcube_calendar_ui(settings) $dialog.find('div.event-section, div.event-line, .form-group').hide(); $('#event-title').html(Q(event.title)).show(); - + if (event.location) $('#event-location').html('@ ' + text2html(event.location)).show(); if (event.description) $('#event-description').show().find('.event-text').html(text2html(event.description, 300, 6)); if (event.vurl) $('#event-url').show().find('.event-text').html(render_link(event.vurl)); - - // render from-to in a nice human-readable way - // -> now shown in dialog title - // $('#event-date').html(Q(me.event_date_text(event))).show(); - if (event.recurrence && event.recurrence_text) $('#event-repeat').show().find('.event-text').html(Q(event.recurrence_text)); - if (event.valarms && event.alarms_text) $('#event-alarm').show().find('.event-text').html(Q(event.alarms_text).replace(',', ',
    ')); - if (calendar.name) $('#event-calendar').show().find('.event-text').text(calendar.name).addClass('cal-'+calendar.id); if (event.categories) @@ -2496,7 +2534,7 @@ function rcube_calendar_ui(settings) event.editable = false; event.temp = true; - event.className = ['fc-event-cal-'+data.calendar, 'fc-event-temp']; + event.className = ['fc-event-temp']; fc.fullCalendar(data.id ? 'updateEvent' : 'renderEvent', event); @@ -3408,28 +3446,13 @@ function rcube_calendar_ui(settings) // register the given calendar to the current view var add_calendar_source = function(cal) { - var color, brightness, select, id = cal.id; + var brightness, select, id = cal.id; me.calendars[id] = $.extend({ url: rcmail.url('calendar/load_events', { source: id }), - className: ['fc-event-cal-' + id], id: id }, cal); - // choose black text color when background is bright, white otherwise - if (color = settings.event_coloring % 2 ? '' : '#' + cal.color) { - me.calendars[id].color = color; - me.calendars[id].textColor = 'white'; - - if (/^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i.test(color)) { - // use information about brightness calculation found at - // http://javascriptrules.com/2009/08/05/css-color-brightness-contrast-using-javascript/ - brightness = (parseInt(RegExp.$1, 16) * 299 + parseInt(RegExp.$2, 16) * 587 + parseInt(RegExp.$3, 16) * 114) / 1000; - if (brightness > 125) - me.calendars[id].textColor = '#222'; - } - } - if (fc && (cal.active || cal.subscribed)) { if (cal.active) fc.fullCalendar('addEventSource', me.calendars[id]); @@ -3648,7 +3671,6 @@ function rcube_calendar_ui(settings) if (rcmail.env.itip_events && rcmail.env.itip_events.length) { me.calendars['--invitation--itip'] = { events: rcmail.env.itip_events, - className: ['fc-event-cal---invitation--itip'], color: '#fff', textColor: '#333', editable: false, @@ -3750,6 +3772,7 @@ function rcube_calendar_ui(settings) }, viewRender: function(view, element) { $('#agendaoptions')[view.name == 'list' ? 'show' : 'hide'](); + if (minical) { window.setTimeout(function(){ minical.datepicker('setDate', fc.fullCalendar('getDate').toDate()); }, exec_deferred); if (view.name != current_view) @@ -3758,16 +3781,20 @@ function rcube_calendar_ui(settings) me.update_state(); } - if (view.name == 'list') { - var viewStart = moment(view.start); + var viewStart = moment(view.start); - $('#calendar .fc-prev-button').off('click').on('click', function() { + $('#calendar .fc-prev-button').off('click').on('click', function() { + if (view.name == 'list') fc.fullCalendar('gotoDate', viewStart.subtract(settings.agenda_range, 'days')); - }); - $('#calendar .fc-next-button').off('click').on('click', function() { + else + fc.fullCalendar('prev'); + }); + $('#calendar .fc-next-button').off('click').on('click', function() { + if (view.name == 'list') fc.fullCalendar('gotoDate', viewStart.add(settings.agenda_range, 'days')); - }); - } + else + fc.fullCalendar('next'); + }); }, eventAfterAllRender: function(view) { if (view.name == 'list') { diff --git a/plugins/calendar/lib/calendar_ui.php b/plugins/calendar/lib/calendar_ui.php index 7a534d5e..a24ce6b6 100644 --- a/plugins/calendar/lib/calendar_ui.php +++ b/plugins/calendar/lib/calendar_ui.php @@ -145,41 +145,30 @@ class calendar_ui */ function calendar_css($attrib = array()) { + $categories = $this->cal->driver->list_categories(); + $js_categories = array(); $mode = $this->rc->config->get('calendar_event_coloring', $this->cal->defaults['calendar_event_coloring']); - $categories = $this->cal->driver->list_categories(); - $css = "\n"; - + $css = "\n"; + foreach ((array)$categories as $class => $color) { - if (empty($color)) - continue; - - $class = 'cat-' . asciiwords(strtolower($class), true); - $css .= ".$class { color: #$color }\n"; - if ($mode > 0) { - if ($mode == 2) { - $css .= ".fc-event-$class .fc-event-bg {"; - $css .= " opacity: 0.9;"; - $css .= " filter: alpha(opacity=90);"; - } - else { - $css .= ".fc-event-$class.fc-event-skin, "; - $css .= ".fc-event-$class .fc-event-skin, "; - $css .= ".fc-event-$class .fc-event-inner {"; - } - $css .= " background-color: #" . $color . ";"; - if ($mode % 2) - $css .= " border-color: #$color;"; - $css .= "}\n"; + if (!empty($color)) { + $js_categories[$class] = $color; + + $color = ltrim($color, '#'); + $class = 'cat-' . asciiwords(strtolower($class), true); + $css .= ".$class { color: #$color; }\n"; } } - + + $this->rc->output->set_env('calendar_categories', $js_categories); + $calendars = $this->cal->driver->list_calendars(); foreach ((array)$calendars as $id => $prop) { - if (!$prop['color']) - continue; - $css .= $this->calendar_css_classes($id, $prop, $mode, $attrib); + if ($prop['color']) { + $css .= $this->calendar_css_classes($id, $prop, $mode, $attrib); + } } - + return html::tag('style', array('type' => 'text/css'), $css); } @@ -192,29 +181,12 @@ class calendar_ui // replace white with skin-defined color if (!empty($attrib['folder-fallback-color']) && preg_match('/^f+$/i', $folder_color)) { - $folder_color = $attrib['folder-fallback-color']; + $folder_color = ltrim($attrib['folder-fallback-color'], '#'); } $class = 'cal-' . asciiwords($id, true); $css = str_replace('$class', $class, $attrib['folder-class']) ?: "li .$class"; - $css .= ", #eventshow .$class { color: #$folder_color; }\n"; - - if ($mode != 1) { - if ($mode == 3) { - $css .= ".fc-event-$class .fc-event-bg {"; - $css .= " opacity: 0.9;"; - $css .= " filter: alpha(opacity=90);"; - } - else { - $css .= ".fc-event-$class, "; - $css .= ".fc-event-$class .fc-event-inner {"; - } - if (!$prop['printmode']) - $css .= " background-color: #$color;"; - if ($mode % 2 == 0) - $css .= " border-color: #$color;"; - $css .= "}\n"; - } + $css .= " { color: #$folder_color; }\n"; return $css . ".$class .handle { background-color: #$color; }\n"; } diff --git a/plugins/calendar/print.js b/plugins/calendar/print.js index 57cb05a7..fa9a3249 100644 --- a/plugins/calendar/print.js +++ b/plugins/calendar/print.js @@ -55,7 +55,7 @@ window.rcmail && rcmail.addEventListener('init', function(evt) { source.color = '#' + source.color.replace(/^#/, ''); - if (source.color == '#ffffff') + if (source.color.match(/^#f+$/i)) source.color = '#ccc'; event_sources.push(source); diff --git a/plugins/calendar/skins/elastic/templates/calendar.html b/plugins/calendar/skins/elastic/templates/calendar.html index bfea051c..0167283e 100644 --- a/plugins/calendar/skins/elastic/templates/calendar.html +++ b/plugins/calendar/skins/elastic/templates/calendar.html @@ -54,10 +54,10 @@
    diff --git a/plugins/calendar/skins/larry/calendar.css b/plugins/calendar/skins/larry/calendar.css index 4df834ea..75ab4ce7 100644 --- a/plugins/calendar/skins/larry/calendar.css +++ b/plugins/calendar/skins/larry/calendar.css @@ -1828,8 +1828,7 @@ a.dropdown-link:after { } .fc-event .fc-bg { - opacity: 1; - background: unset; + opacity: .15; margin-top: 14px; cursor: pointer; } @@ -1864,6 +1863,12 @@ a.dropdown-link:after { color: #888; } +.fc-list-table tr.fc-invitation-tentative .fc-event-dot, +.fc-list-table tr.fc-invitation-declined .fc-event-dot, +.fc-list-table tr.fc-invitation-needs-action .fc-event-dot { + background-color: #aaa; +} + .fc-list-table tr.fc-invitation-tentative td.fc-list-item-title, .fc-list-table tr.fc-invitation-declined td.fc-list-item-title, .fc-list-table tr.fc-invitation-needs-action td.fc-list-item-title { diff --git a/plugins/libcalendaring/libcalendaring.js b/plugins/libcalendaring/libcalendaring.js index f4e9dc91..d328b19c 100644 --- a/plugins/libcalendaring/libcalendaring.js +++ b/plugins/libcalendaring/libcalendaring.js @@ -43,6 +43,7 @@ function rcube_libcalendaring(settings) var me = this; var gmt_offset = (new Date().getTimezoneOffset() / -60) - (settings.timezone || 0) - (settings.dst || 0); var client_timezone = new Date().getTimezoneOffset(); + var color_map = {}; // general datepicker settings this.datepicker_settings = { @@ -333,6 +334,33 @@ function rcube_libcalendaring(settings) return date; } + /** + * Finds text color for specified background color + */ + this.text_color = function(color) + { + var res = '#222'; + + if (!color) { + return res; + } + + if (!color_map[color]) { + color_map[color] = '#fff'; + + if (/^#?([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i.test(color)) { + // use information about brightness calculation found at + // http://javascriptrules.com/2009/08/05/css-color-brightness-contrast-using-javascript/ + brightness = (parseInt(RegExp.$1, 16) * 299 + parseInt(RegExp.$2, 16) * 587 + parseInt(RegExp.$3, 16) * 114) / 1000; + if (brightness > 125) { + color_map[color] = res; + } + } + } + + return color_map[color]; + } + /** * Simple plaintext to HTML converter, makig URLs clickable */ diff --git a/plugins/libkolab/skins/elastic/include/calendar.less b/plugins/libkolab/skins/elastic/include/calendar.less index 8e7695df..eec663b5 100644 --- a/plugins/libkolab/skins/elastic/include/calendar.less +++ b/plugins/libkolab/skins/elastic/include/calendar.less @@ -210,6 +210,7 @@ fieldset.categories .input-group { @color-calendar-border: @color-layout-border; @color-calendar-free-bg: fadeout(@color-black-shade-text, 80%); @color-calendar-today: fadeout(@color-warning, 80%); +@color-event-default: #c00; .fc { body.quickview-active & .fc-scroller { @@ -262,7 +263,7 @@ fieldset.categories .input-group { button { height: unset; - padding: .375rem .75rem; + padding: .3rem .75rem; } button.prev:before { @@ -297,23 +298,38 @@ fieldset.categories .input-group { } } + .fc-event-dot { + background-color: @color-event-default; + } + + a.fc-event, a.fc-event:hover { + color: #fff; + } + .fc-event { - font-size: 1rem; + font-size: 13px; + background-color: @color-event-default; + border-color: @color-event-default; .fc-title { font-weight: bold; } + .fc-bg { + opacity: .15; + margin-top: 1.1rem; + } + &.fc-invitation-needs-action { - border: 1px dashed #5757c7 !important; + border: 1px dashed #5757c7; } &.fc-invitation-tentative { - border: 1px dashed #eb8900 !important; + border: 1px dashed #eb8900; } &.fc-invitation-declined { - border: 1px dashed #c00 !important; + border: 1px dashed #c00; } &.fc-event-ns-other.fc-invitation-declined { @@ -342,6 +358,10 @@ fieldset.categories .input-group { tr.fc-invitation-declined, tr.fc-invitation-needs-action { color: #888; + + .fc-event-dot { + background-color: #888; + } } } From 8400bbe36ffb1cc3d2d2c4684127b94f927ba2a0 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Thu, 7 Feb 2019 13:15:41 +0000 Subject: [PATCH 24/98] T4770: Fix searching by event categories --- plugins/calendar/drivers/kolab/kolab_calendar.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php index 8667b4da..e4459761 100644 --- a/plugins/calendar/drivers/kolab/kolab_calendar.php +++ b/plugins/calendar/drivers/kolab/kolab_calendar.php @@ -40,7 +40,7 @@ class kolab_calendar extends kolab_storage_folder_api protected $cal; protected $events = array(); - protected $search_fields = array('title', 'description', 'location', 'attendees'); + protected $search_fields = array('title', 'description', 'location', 'attendees', 'categories'); /** * Factory method to instantiate a kolab_calendar object From 2a66eed29a5665f4909ec995746b24210566bb23 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Fri, 8 Feb 2019 13:16:38 +0100 Subject: [PATCH 25/98] Fix javascript errors in Availability dialog --- plugins/calendar/calendar_ui.js | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js index e7a2fee6..102482c5 100644 --- a/plugins/calendar/calendar_ui.js +++ b/plugins/calendar/calendar_ui.js @@ -1448,8 +1448,11 @@ function rcube_calendar_ui(settings) // render overlay element over the grid to visiualize the current event date/time var render_freebusy_overlay = function() { - var overlay = $('#schedule-event-time'); - if (me.selected_event.end.getTime() <= freebusy_ui.start.getTime() || me.selected_event.start.getTime() >= freebusy_ui.end.getTime()) { + var overlay = $('#schedule-event-time'), + event_start = 'toDate' in me.selected_event.start ? me.selected_event.start.toDate() : me.selected_event.start; + event_end = 'toDate' in me.selected_event.end ? me.selected_event.end.toDate() : me.selected_event.end; + + if (event_end.getTime() <= freebusy_ui.start.getTime() || event_start.getTime() >= freebusy_ui.end.getTime()) { overlay.hide(); if (overlay.data('isdraggable')) overlay.draggable('disable'); @@ -1716,7 +1719,7 @@ function rcube_calendar_ui(settings) }); } }; - + // write changed event date/times back to form fields var update_freebusy_dates = function(start, end) { @@ -1812,8 +1815,8 @@ function rcube_calendar_ui(settings) // if candidate is big enough, this is it! if (candidatecount == numslots) { - event.start.setTime(candidatestart); - event.end.setTime(candidatestart + duration); + 'toDate' in event.start ? (event.start = new Date(candidatestart)) : event.start.setTime(candidatestart); + 'toDate' in event.end ? (event.end = new Date(candidatestart + duration)) : event.end.setTime(candidatestart + duration); success = true; break; } @@ -1822,17 +1825,20 @@ function rcube_calendar_ui(settings) // update event date/time display if (success) { update_freebusy_dates(event.start, event.end); - + // move freebusy grid if necessary - var offset = Math.ceil((event.start.getTime() - freebusy_ui.end.getTime()) / DAY_MS); - if (event.start.getTime() >= freebusy_ui.end.getTime()) + var event_start = 'toDate' in event.start ? event.start.toDate() : event.start, + event_end = 'toDate' in event.end ? event.end.toDate() : event.end, + offset = Math.ceil((event_start.getTime() - freebusy_ui.end.getTime()) / DAY_MS); + + if (event_start.getTime() >= freebusy_ui.end.getTime()) render_freebusy_grid(Math.max(1, offset)); - else if (event.end.getTime() <= freebusy_ui.start.getTime()) + else if (event_end.getTime() <= freebusy_ui.start.getTime()) render_freebusy_grid(Math.min(-1, offset)); else render_freebusy_overlay(); - var now = new Date(), disabled = event.start.getTime() < now.getTime(); + var now = new Date(), disabled = event_start.getTime() < now.getTime(); // FIXME: .button() does nothing in Elastic skin $('#schedule-find-prev').button('option', 'disabled', disabled).prop('disabled', disabled); From 721e131b53703089c9c1e9ad393aa35e94dad362 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Fri, 8 Feb 2019 13:22:46 +0100 Subject: [PATCH 26/98] Add missing styles for some elements in Availability finder table --- plugins/libkolab/skins/elastic/include/calendar.less | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/libkolab/skins/elastic/include/calendar.less b/plugins/libkolab/skins/elastic/include/calendar.less index eec663b5..33fdc76c 100644 --- a/plugins/libkolab/skins/elastic/include/calendar.less +++ b/plugins/libkolab/skins/elastic/include/calendar.less @@ -1151,6 +1151,10 @@ body.task-calendar { transform: rotate(28deg) translate(-7%); } + &.w33 span { + transform: rotate(32deg) translate(-5%); + } + &.w40 span { transform: rotate(36deg) translate(-3%); } @@ -1159,6 +1163,10 @@ body.task-calendar { transform: rotate(48deg) translate(6%); } + &.w67 span { + transform: rotate(52deg) translate(9%); + } + &.w70 span, &.w75 span { transform: rotate(55deg) translate(12%, 30%); From b1640e16f4939e6ba6711e2eba5a5057ba72482d Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Mon, 18 Feb 2019 12:04:08 +0100 Subject: [PATCH 27/98] Fix misleading error message on IMAP errors --- plugins/libkolab/lib/kolab_storage.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/plugins/libkolab/lib/kolab_storage.php b/plugins/libkolab/lib/kolab_storage.php index ceacaa75..9715b2a6 100644 --- a/plugins/libkolab/lib/kolab_storage.php +++ b/plugins/libkolab/lib/kolab_storage.php @@ -79,10 +79,10 @@ class kolab_storage return true; $rcmail = rcube::get_instance(); - self::$config = $rcmail->config; + self::$config = $rcmail->config; self::$version = strval($rcmail->config->get('kolab_format_version', self::$version)); - self::$imap = $rcmail->get_storage(); - self::$ready = class_exists('kolabformat') && + self::$imap = $rcmail->get_storage(); + self::$ready = class_exists('kolabformat') && (self::$imap->get_capability('METADATA') || self::$imap->get_capability('ANNOTATEMORE') || self::$imap->get_capability('ANNOTATEMORE2')); if (self::$ready) { @@ -96,8 +96,7 @@ class kolab_storage } else { rcube::raise_error(array( - 'code' => 900, 'type' => 'php', - 'message' => "IMAP server doesn't support METADATA or ANNOTATEMORE" + 'code' => 900, 'type' => 'php', 'message' => "IMAP error" ), true); } From ea21949fd84ac9fc2e2640f69fdde15ed4d5dcbe Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Tue, 19 Feb 2019 12:33:46 +0100 Subject: [PATCH 28/98] kolab_auth_proxy plugin (Bifrost#T184892) --- plugins/kolab_auth_proxy/LICENSE | 661 ++++++++++++++++++ plugins/kolab_auth_proxy/README | 31 + plugins/kolab_auth_proxy/composer.json | 25 + plugins/kolab_auth_proxy/config.inc.php.dist | 30 + plugins/kolab_auth_proxy/kolab_auth_proxy.php | 113 +++ 5 files changed, 860 insertions(+) create mode 100644 plugins/kolab_auth_proxy/LICENSE create mode 100644 plugins/kolab_auth_proxy/README create mode 100644 plugins/kolab_auth_proxy/composer.json create mode 100644 plugins/kolab_auth_proxy/config.inc.php.dist create mode 100644 plugins/kolab_auth_proxy/kolab_auth_proxy.php diff --git a/plugins/kolab_auth_proxy/LICENSE b/plugins/kolab_auth_proxy/LICENSE new file mode 100644 index 00000000..dba13ed2 --- /dev/null +++ b/plugins/kolab_auth_proxy/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/plugins/kolab_auth_proxy/README b/plugins/kolab_auth_proxy/README new file mode 100644 index 00000000..2c93a14c --- /dev/null +++ b/plugins/kolab_auth_proxy/README @@ -0,0 +1,31 @@ +Proxy authentication for Kolab +------------------------------ + +This plugin adds ability for configured external app/user to impersonate +as another user in services based on Roundcube Framework. + +Currently it works with Kolab iRony only, with one limitation - external file storages +are not accessible. + +CONFIGURATION +------------- + +1. In iRony config set: + + $config['kolabdav_plugins'] = array('kolab_auth_proxy', 'kolab_auth'); + + Note: kolab_auth_proxy MUST be before kolab_auth. + +2. In plugin config set: + + $config['kolab_auth_proxy_user'] = 'proxy'; + $config['kolab_auth_proxy_pass'] = '12345'; + $config['kolab_auth_proxy_imap_user'] = 'cyrus-admin'; + $config['kolab_auth_proxy_imap_pass'] = 'password'; + +After this you should be able to use *DAV services using HTTP basic authentication +with login: proxy**username and password: 12345, where "username" is the login of +the user you want to impersonate as. + +Note that there are more options in config if you need working functionality +that involves accessing SMTP or LDAP. diff --git a/plugins/kolab_auth_proxy/composer.json b/plugins/kolab_auth_proxy/composer.json new file mode 100644 index 00000000..dc96e2c8 --- /dev/null +++ b/plugins/kolab_auth_proxy/composer.json @@ -0,0 +1,25 @@ +{ + "name": "kolab/kolab_auth_proxy", + "type": "roundcube-plugin", + "description": "Proxy authentication for Kolab", + "homepage": "https://git.kolab.org/diffusion/RPK/", + "license": "AGPLv3", + "version": "3.4.2", + "authors": [ + { + "name": "Aleksander Machniak", + "email": "machniak@kolabsys.com", + "role": "Lead" + } + ], + "repositories": [ + { + "type": "composer", + "url": "https://plugins.roundcube.net" + } + ], + "require": { + "php": ">=5.3.0", + "roundcube/plugin-installer": ">=0.1.3" + } +} diff --git a/plugins/kolab_auth_proxy/config.inc.php.dist b/plugins/kolab_auth_proxy/config.inc.php.dist new file mode 100644 index 00000000..9233b578 --- /dev/null +++ b/plugins/kolab_auth_proxy/config.inc.php.dist @@ -0,0 +1,30 @@ +** +$config['kolab_auth_proxy_user'] = ''; + +// Proxy user password +$config['kolab_auth_proxy_pass'] = ''; + +// IMAP (master) user +$config['kolab_auth_proxy_imap_user'] = 'cyrus-admin'; + +// IMAP (master) password +$config['kolab_auth_proxy_imap_pass'] = ''; + +// SMTP server host +// To override the SMTP port or connection method, provide a full URL like 'tls://somehost:587' +$config['kolab_auth_proxy_smtp_server'] = ''; + +// SMTP username +$config['kolab_auth_proxy_smtp_user'] = ''; + +// SMTP password +$config['kolab_auth_proxy_smtp_pass'] = ''; + +// LDAP user DN +$config['kolab_auth_proxy_ldap_user'] = 'uid=kolab-service,ou=Special Users,dc=example,dc=org'; + +// LDAP password +$config['kolab_auth_proxy_ldap_pass'] = ''; diff --git a/plugins/kolab_auth_proxy/kolab_auth_proxy.php b/plugins/kolab_auth_proxy/kolab_auth_proxy.php new file mode 100644 index 00000000..743d7a1d --- /dev/null +++ b/plugins/kolab_auth_proxy/kolab_auth_proxy.php @@ -0,0 +1,113 @@ + + * + * Copyright (C) 2019, Kolab Systems AG + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +class kolab_auth_proxy extends rcube_plugin +{ + /** + * Plugin initialization + */ + public function init() + { + // Only iRony for now + if (defined('KOLAB_DAV_VERSION')) { + $this->add_hook('authenticate', array($this, 'authenticate')); + } + } + + /** + * Authenticate hook handler + */ + public function authenticate($args) + { + $this->load_config(); + $this->rc = rcube::get_instance(); + + $proxy_user = $this->rc->config->get('kolab_auth_proxy_user'); + $proxy_pass = $this->rc->config->get('kolab_auth_proxy_pass'); + + // Login is in a form of: ** + + if ($proxy_user && $args['pass'] === $proxy_pass + && strpos($args['user'], $proxy_user . '**') === 0 + && ($target = substr($args['user'], strlen($proxy_user . '**'))) + ) { + $args['user'] = $target; + $args['pass'] = '-dummy-'; // cannot be empty + + // Disable iRony's auth cache, otherwise 'authenticate' hook will not + // be executed on each request + $args['no-cache'] = true; + + $this->add_hook('storage_connect', array($this, 'storage_connect')); +// $this->add_hook('managesieve_connect', array($this, 'storage_connect')); + $this->add_hook('smtp_connect', array($this, 'smtp_connect')); + $this->add_hook('ldap_connected', array($this, 'ldap_connected')); + } + + return $args; + } + + /** + * Storage_connect/managesieve_connect hook handler + */ + public function storage_connect($args) + { + $imap_user = $this->rc->config->get('kolab_auth_proxy_imap_user'); + $imap_pass = $this->rc->config->get('kolab_auth_proxy_imap_pass'); + + $args['auth_cid'] = $imap_user; + $args['auth_pw'] = $imap_pass; + $args['auth_type'] = 'PLAIN'; + + return $args; + } + + /** + * Smtp_connect hook handler + */ + public function smtp_connect($args) + { + foreach (array('smtp_server', 'smtp_user', 'smtp_pass') as $prop) { + $args[$prop] = $this->rc->config->get("kolab_auth_proxy_$prop", $args[$prop]); + } + + return $args; + } + + /** + * ldap_connected hook handler + */ + public function ldap_connected($args) + { + $ldap_user = $this->rc->config->get('kolab_auth_proxy_ldap_user'); + $ldap_pass = $this->rc->config->get('kolab_auth_proxy_ldap_pass'); + + if ($ldap_user && $ldap_pass && $args['user_specific']) { + $args['bind_dn'] = $ldap_user; + $args['bind_pass'] = $ldap_pass; + $args['search_filter'] = null; + } + + return $args; + } +} From 9b55d3ad1b8735e3c6eb0c2560efc7d8b00ebd9c Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Wed, 20 Feb 2019 10:25:09 +0100 Subject: [PATCH 29/98] Fix invalid HTML output --- plugins/calendar/lib/calendar_ui.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/calendar/lib/calendar_ui.php b/plugins/calendar/lib/calendar_ui.php index a24ce6b6..37b7b44d 100644 --- a/plugins/calendar/lib/calendar_ui.php +++ b/plugins/calendar/lib/calendar_ui.php @@ -308,7 +308,7 @@ class calendar_ui $content = html::div(join(' ', $classes), html::a(array('class' => 'calname', 'id' => $label_id, 'title' => $title, 'href' => '#'), rcube::Q($prop['editname'] ?: $prop['listname'])) . ($prop['virtual'] ? '' : - html::tag('input', array('type' => 'checkbox', 'name' => '_cal[]', 'value' => $id, 'checked' => $prop['active'], 'aria-labelledby' => $label_id), '') . + html::tag('input', array('type' => 'checkbox', 'name' => '_cal[]', 'value' => $id, 'checked' => $prop['active'], 'aria-labelledby' => $label_id)) . html::span('actions', ($prop['removable'] ? html::a(array('href' => '#', 'class' => 'remove', 'title' => $this->cal->gettext('removelist')), ' ') : '') . html::a(array('href' => '#', 'class' => 'quickview', 'title' => $this->cal->gettext('quickview'), 'role' => 'checkbox', 'aria-checked' => 'false'), '') . From 80ed46693a4d452fa20b6b6ff5de3463b20513fc Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Wed, 20 Feb 2019 12:45:16 +0100 Subject: [PATCH 30/98] Elastic: Fix non-working completion status checkbox on tasks list --- plugins/tasklist/tasklist.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/plugins/tasklist/tasklist.js b/plugins/tasklist/tasklist.js index d0588248..efae4f06 100644 --- a/plugins/tasklist/tasklist.js +++ b/plugins/tasklist/tasklist.js @@ -360,16 +360,19 @@ function rcube_tasklist_ui(settings) }).find('input[type=text]').placeholder(rcmail.gettext('createnewtask','tasklist')); // click-handler on task list items (delegate) - $(rcmail.gui_objects.resultlist).on('click', function(e){ - var item = $(e.target); - var className = e.target.className; + $(rcmail.gui_objects.resultlist).on('click', function(e) { + var item = $(e.target), className = e.target.className; if (item.hasClass('childtoggle')) { item = item.parent().find('.taskhead'); className = 'childtoggle'; } - else if (!item.hasClass('taskhead')) - item = item.closest('div.taskhead'); + else { + if (!item.hasClass('taskhead')) + item = item.closest('div.taskhead'); + + className = String(className).split(' ')[0]; + } // ignore if (!item.length) From 7288bac122302f76b3e2ef01b6e9e1cb78488d23 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Wed, 20 Feb 2019 13:40:56 +0100 Subject: [PATCH 31/98] Elastic: Use custom switch in place of pretty checkbox --- plugins/calendar/calendar_ui.js | 4 +-- .../skins/elastic/templates/search_addon.html | 2 +- plugins/kolab_notes/notes.js | 2 +- .../skins/elastic/include/calendar.less | 26 +++-------------- .../skins/elastic/include/libcalendaring.less | 16 ++-------- .../skins/elastic/include/tasklist.less | 15 +++------- plugins/libkolab/skins/elastic/libkolab.less | 29 ++++--------------- plugins/tasklist/tasklist.js | 4 +-- 8 files changed, 21 insertions(+), 77 deletions(-) diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js index 102482c5..9242d676 100644 --- a/plugins/calendar/calendar_ui.js +++ b/plugins/calendar/calendar_ui.js @@ -3650,10 +3650,10 @@ function rcube_calendar_ui(settings) // Make Elastic checkboxes pretty if (window.UI && UI.pretty_checkbox) { $(rcmail.gui_objects.calendarslist).find('input[type=checkbox]').each(function() { - UI.pretty_checkbox($(this).addClass('flex-checkbox')); + UI.pretty_checkbox(this); }); calendars_list.addEventListener('add-item', function(prop) { - UI.pretty_checkbox($(prop.li).find('input').addClass('flex-checkbox')); + UI.pretty_checkbox($(prop.li).find('input')); }); } diff --git a/plugins/kolab_addressbook/skins/elastic/templates/search_addon.html b/plugins/kolab_addressbook/skins/elastic/templates/search_addon.html index 790f3875..5b883ae4 100644 --- a/plugins/kolab_addressbook/skins/elastic/templates/search_addon.html +++ b/plugins/kolab_addressbook/skins/elastic/templates/search_addon.html @@ -11,7 +11,7 @@ rcmail.addEventListener('init', function() { // Make checkboxes pretty rcmail.treelist.addEventListener('add-item', function(prop) { - UI.pretty_checkbox($(prop.li).find('input').addClass('flex-checkbox')); + UI.pretty_checkbox($(prop.li).find('input')); }); }); } diff --git a/plugins/kolab_notes/notes.js b/plugins/kolab_notes/notes.js index 69852d72..c459e512 100644 --- a/plugins/kolab_notes/notes.js +++ b/plugins/kolab_notes/notes.js @@ -170,7 +170,7 @@ function rcube_kolab_notes_ui(settings) // Make Elastic checkboxes pretty if (window.UI && UI.pretty_checkbox) { notebookslist.addEventListener('add-item', function(prop) { - UI.pretty_checkbox($(prop.li).find('input').addClass('flex-checkbox')); + UI.pretty_checkbox($(prop.li).find('input')); }); } diff --git a/plugins/libkolab/skins/elastic/include/calendar.less b/plugins/libkolab/skins/elastic/include/calendar.less index 33fdc76c..4acae1bf 100644 --- a/plugins/libkolab/skins/elastic/include/calendar.less +++ b/plugins/libkolab/skins/elastic/include/calendar.less @@ -846,16 +846,12 @@ body.task-calendar { // fixes additional checkbox in Elastic's .datetime widget .datetime { - label { - margin-left: 1em; - margin-top: .4rem; + .custom-switch { + padding-left: .5rem; label { - line-height: 1; - - &:before { - margin-right: .25rem; - } + line-height: 2; + margin-top: .2rem; } } @@ -863,10 +859,6 @@ body.task-calendar { width: 10em !important; } - input[type=checkbox] { - width: auto !important; - } - @media screen and (max-width: 420px) { input { width: 8em !important; @@ -920,16 +912,6 @@ body.task-calendar { order: 100; margin-left: 0; } - - label { - vertical-align: middle; - } - - input.icon-checkbox + label:before { - margin-right:.25rem; - display: inline; - float: none; - } } .schedule-nav { diff --git a/plugins/libkolab/skins/elastic/include/libcalendaring.less b/plugins/libkolab/skins/elastic/include/libcalendaring.less index a21462c1..37d7796c 100644 --- a/plugins/libkolab/skins/elastic/include/libcalendaring.less +++ b/plugins/libkolab/skins/elastic/include/libcalendaring.less @@ -267,9 +267,8 @@ } td.invite { - label:before { - line-height: 1.6; - height: 1.5em; + .custom-switch { + margin-top: .15rem; } } @@ -343,17 +342,6 @@ } } -html.touch { - .edit-attendees-table { - td.invite { - label:before { - line-height: 1.2; - height: 1.2em; - } - } - } -} - .form-searchbar { display: flex; margin-bottom: .5rem; diff --git a/plugins/libkolab/skins/elastic/include/tasklist.less b/plugins/libkolab/skins/elastic/include/tasklist.less index 781bd248..1a220467 100644 --- a/plugins/libkolab/skins/elastic/include/tasklist.less +++ b/plugins/libkolab/skins/elastic/include/tasklist.less @@ -217,18 +217,11 @@ } } - input + label, - input.complete { + .custom-switch { position: absolute; - right: .25rem; - bottom: 0; - top: auto; - padding: 0 .2em 0 0; - cursor: pointer; + top: 1.4rem; z-index: 1; - line-height: 1; - height: 1.5em; - font-size: 1.15em; + height: 2.3em; } .actions { @@ -255,7 +248,7 @@ html.touch #tasklist { span.flagged, input[type=checkbox], - .icon-checkbox + label { + .custom-switch { display: none; } diff --git a/plugins/libkolab/skins/elastic/libkolab.less b/plugins/libkolab/skins/elastic/libkolab.less index a32e64b5..0aefa0cc 100644 --- a/plugins/libkolab/skins/elastic/libkolab.less +++ b/plugins/libkolab/skins/elastic/libkolab.less @@ -65,6 +65,10 @@ } } + .custom-switch { + position: relative; + } + &.folder .listname:before { &:extend(.font-icon-class); content: @fa-var-sticky-note; @@ -193,18 +197,6 @@ } } - input.flex-checkbox { - position: relative !important; - margin: 0 0 0 .25em !important; - - & + label { - position: relative !important; - margin: 0 .3em 0 -1em !important; - right: 0 !important; - font-size: 1.15em; - } - } - li.droptarget > div { background-color: @color-list-droptarget-background; } @@ -381,13 +373,6 @@ a.history { label { order: 10; } - - .icon-checkbox + label { - order: unset; - min-width: 2em; - padding: 0; - line-height: 1; - } } button.btn.save.notify:before { @@ -416,6 +401,7 @@ button.btn.print:before { } .prop { + line-height: 2; margin-left: .5rem; display: inline-block; vertical-align: middle; @@ -423,11 +409,6 @@ button.btn.print:before { label { margin: 0; } - - label:before { - line-height: 1.25; - margin-right: .25rem; - } } @media print { diff --git a/plugins/tasklist/tasklist.js b/plugins/tasklist/tasklist.js index efae4f06..7853df3f 100644 --- a/plugins/tasklist/tasklist.js +++ b/plugins/tasklist/tasklist.js @@ -219,10 +219,10 @@ function rcube_tasklist_ui(settings) // Make Elastic checkboxes pretty if (window.UI && UI.pretty_checkbox) { $(rcmail.gui_objects.tasklistslist).find('input[type=checkbox]').each(function() { - UI.pretty_checkbox($(this).addClass('flex-checkbox')); + UI.pretty_checkbox(this); }); tasklists_widget.addEventListener('add-item', function(prop) { - UI.pretty_checkbox($(prop.li).find('input').addClass('flex-checkbox')); + UI.pretty_checkbox($(prop.li).find('input')); }); } From f5c586cf7bdc0f5e6088de81ec4e4f6a7bb944ff Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Thu, 21 Feb 2019 11:22:31 +0000 Subject: [PATCH 32/98] Fix some labels in import/export dialogs not pointing to inputs/selects --- plugins/calendar/lib/calendar_ui.php | 3 ++- plugins/tasklist/tasklist.js | 24 ++++++++++++++++++------ plugins/tasklist/tasklist_ui.php | 3 ++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/plugins/calendar/lib/calendar_ui.php b/plugins/calendar/lib/calendar_ui.php index 37b7b44d..79b631d7 100644 --- a/plugins/calendar/lib/calendar_ui.php +++ b/plugins/calendar/lib/calendar_ui.php @@ -513,6 +513,7 @@ class calendar_ui } $input = new html_inputfield(array( + 'id' => 'importfile', 'type' => 'file', 'name' => '_data', 'size' => $attrib['uploadfieldsize'], @@ -533,7 +534,7 @@ class calendar_ui $html = html::div('form-section form-group row', html::label(array('class' => 'col-sm-4 col-form-label', 'for' => 'importfile'), rcube::Q($this->rc->gettext('importfromfile'))) . html::div('col-sm-8', $input->show() - . html::div('hint', $this->rc->gettext(array('id' => 'importfile', 'name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize))))) + . html::div('hint', $this->rc->gettext(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize))))) ); $html .= html::div('form-section form-group row', diff --git a/plugins/tasklist/tasklist.js b/plugins/tasklist/tasklist.js index 7853df3f..731e56c2 100644 --- a/plugins/tasklist/tasklist.js +++ b/plugins/tasklist/tasklist.js @@ -862,6 +862,16 @@ function rcube_tasklist_ui(settings) loadstate.lists = active_lists(); } + var init_cloned_form = function(form) { + // update element IDs after clone + $('select,input,label', form).each(function() { + if (this.htmlFor) + this.htmlFor += '-clone'; + else if (this.id) + this.id += '-clone'; + }); + } + // open a dialog to upload an .ics file with tasks to be imported this.import_tasks = function(tasklist) { @@ -876,6 +886,8 @@ function rcube_tasklist_ui(settings) if (tasklist) $('#task-import-list').val(tasklist); + init_cloned_form(form); + buttons[rcmail.gettext('import', 'tasklist')] = function() { if (form && form.elements._data.value) { rcmail.async_upload_form(form, 'import', function(e) { @@ -939,22 +951,22 @@ function rcube_tasklist_ui(settings) this.export_tasks = function() { // close show dialog first - var $dialog = $("#tasksexport").clone(true).removeClass('uidialog'), + var list, $dialog = $("#tasksexport").clone(true).removeClass('uidialog'), form = $dialog.find('form').get(0), buttons = {}; if ($dialog.is(':ui-dialog')) $dialog.dialog('close'); - $("#task-export-list").val(''); + list = $("#task-export-list").val(''); + + init_cloned_form(form); buttons[rcmail.gettext('export', 'tasklist')] = function() { - var data = {}, - source = $('#task-export-list').val(), - form_elements = $('select, input', form); + var data = {}, form_elements = $('select, input', form); // "current view" export, use hidden form to POST task IDs - if (source === '') { + if (list.val() === '') { var cache = {}, tasks = [], inputs = [], postform = $('#tasks-export-form-post'); diff --git a/plugins/tasklist/tasklist_ui.php b/plugins/tasklist/tasklist_ui.php index c1ac9081..fd999898 100644 --- a/plugins/tasklist/tasklist_ui.php +++ b/plugins/tasklist/tasklist_ui.php @@ -500,6 +500,7 @@ class tasklist_ui } $input = new html_inputfield(array( + 'id' => 'importfile', 'type' => 'file', 'name' => '_data', 'size' => $attrib['uploadfieldsize'], @@ -509,7 +510,7 @@ class tasklist_ui $html = html::div('form-section form-group row', html::label(array('class' => 'col-sm-4 col-form-label', 'for' => 'importfile'), rcube::Q($this->rc->gettext('importfromfile'))) . html::div('col-sm-8', $input->show() - . html::div('hint', $this->rc->gettext(array('id' => 'importfile', 'name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize))))) + . html::div('hint', $this->rc->gettext(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize))))) ); $html .= html::div('form-section form-group row', From 003485ed5e1e4f5c6f588f13f82a5ff8c615cea7 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Thu, 21 Feb 2019 11:30:38 +0000 Subject: [PATCH 33/98] Elastic: Small checkbox label alignment fix --- plugins/kolab_files/lib/kolab_files_engine.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/kolab_files/lib/kolab_files_engine.php b/plugins/kolab_files/lib/kolab_files_engine.php index ede38542..03e682fb 100644 --- a/plugins/kolab_files/lib/kolab_files_engine.php +++ b/plugins/kolab_files/lib/kolab_files_engine.php @@ -350,11 +350,10 @@ class kolab_files_engine 'name' => 'store_passwords', 'value' => '1', 'class' => 'pretty-checkbox', - 'id' => 'auth-pass-checkbox' . $attrib['suffix'], )); - return html::div('auth-options', $checkbox->show(). ' ' - . html::label('auth-pass-checkbox' . $attrib['suffix'], $this->plugin->gettext('storepasswords')) + return html::div('auth-options', + html::label(null, $checkbox->show() . ' ' . $this->plugin->gettext('storepasswords')) . html::p('description hint', $this->plugin->gettext('storepasswordsdesc')) ); } From a9056e4b719b6a7202459368f83ff75fdeecfac7 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Thu, 21 Feb 2019 11:36:53 +0000 Subject: [PATCH 34/98] Notes: Menu options rename: Edit -> Edit/Share notebook, Delete -> Delete notebook --- plugins/kolab_notes/localization/en_US.inc | 3 ++- plugins/kolab_notes/skins/elastic/templates/notes.html | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/kolab_notes/localization/en_US.inc b/plugins/kolab_notes/localization/en_US.inc index 1dffc7aa..d5833e7a 100644 --- a/plugins/kolab_notes/localization/en_US.inc +++ b/plugins/kolab_notes/localization/en_US.inc @@ -27,7 +27,8 @@ $labels['now'] = 'Now'; $labels['sortby'] = 'Sort by'; $labels['newnotebook'] = 'Create a new notebook'; $labels['addnotebook'] = 'Add notebook'; -$labels['editlist'] = 'Edit Notebook'; +$labels['deletelist'] = 'Delete notebook'; +$labels['editlist'] = 'Edit/Share notebook'; $labels['listname'] = 'Name'; $labels['tabsharing'] = 'Sharing'; $labels['discard'] = 'Discard'; diff --git a/plugins/kolab_notes/skins/elastic/templates/notes.html b/plugins/kolab_notes/skins/elastic/templates/notes.html index 0d194053..20dc2976 100644 --- a/plugins/kolab_notes/skins/elastic/templates/notes.html +++ b/plugins/kolab_notes/skins/elastic/templates/notes.html @@ -119,8 +119,8 @@

    From d1989f117648391d1c37419c10058f3a8c43598b Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Thu, 21 Feb 2019 11:42:33 +0000 Subject: [PATCH 35/98] Tasks: Menu options rename: Edit -> Edit/Share list, Delete -> Delete list --- plugins/tasklist/localization/en_US.inc | 3 ++- plugins/tasklist/skins/elastic/templates/mainview.html | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/tasklist/localization/en_US.inc b/plugins/tasklist/localization/en_US.inc index 5223f377..b49e1289 100644 --- a/plugins/tasklist/localization/en_US.inc +++ b/plugins/tasklist/localization/en_US.inc @@ -93,7 +93,8 @@ $labels['tabassignments'] = 'Assignments'; $labels['tabattachments'] = 'Attachments'; $labels['tabsharing'] = 'Sharing'; -$labels['editlist'] = 'Edit list'; +$labels['editlist'] = 'Edit/Share list'; +$labels['deletelist'] = 'Delete list'; $labels['createlist'] = 'Add list'; $labels['listactions'] = 'List options...'; $labels['listname'] = 'Name'; diff --git a/plugins/tasklist/skins/elastic/templates/mainview.html b/plugins/tasklist/skins/elastic/templates/mainview.html index aea44e5f..9845fd77 100644 --- a/plugins/tasklist/skins/elastic/templates/mainview.html +++ b/plugins/tasklist/skins/elastic/templates/mainview.html @@ -255,8 +255,8 @@