Compare commits

...
990 Commits
Author SHA1 Message Date
Ludovic Marcotte efff32e44d Update ChangeLog 2014-11-21 09:13:11 -05:00
Francis Lachapelle f7f78eaba6 Update CKEditor to version 4.4.5 2014-11-21 09:08:36 -05:00
Francis Lachapelle 78ea147383 Update translations 2014-11-21 08:53:12 -05:00
Ludovic Marcotte f7935c6084 Bumped version numbers for the releasex 2014-11-21 08:29:25 -05:00
Ludovic Marcotte 327147f716 Fixed typo 2014-11-19 12:07:50 -05:00
Ludovic Marcotte b4718f363b More documentation fixes for v2.2.10 2014-11-19 12:06:44 -05:00
Ludovic Marcotte 95e3c7ca88 More doc fixes for v2.2.10 2014-11-18 18:36:59 -05:00
Ludovic Marcotte 6bbaf58d43 Initial pass of the doc for v2.2.10 on Debian/Ubuntu 2014-11-18 16:56:45 -05:00
Ludovic Marcotte ac55509aea Updated NEWS file regarding the SOPE commit for bug #2957 2014-11-18 12:45:15 -05:00
Francis Lachapelle 2781fbe0b3 Merge pull request #64 from JensErat/SOGo-asciidoc
Removed erroneous backslash in documentation
2014-11-18 06:17:32 -05:00
Jens Erat 19221beb1f Removed erroneous backslash in documentation 2014-11-18 11:32:12 +01:00
Francis Lachapelle 3d18c94789 Fix extraction of email addresses in some cases
Fixes #2945
2014-11-17 14:33:28 -05:00
Ludovic Marcotte 1f167d9e82 Fixed IMAP searches with non-ASCII folder names 2014-11-17 11:49:56 -05:00
Ludovic Marcotte 3872341a85 Added required patch for previous commit 2014-11-14 10:34:36 -05:00
Ludovic Marcotte b3cd609ae7 Added WindowSize support for GCS collections 2014-11-14 09:13:14 -05:00
Ludovic Marcotte c0f0f2023c added NEWS entry for BSON goodie 2014-11-12 15:09:26 -05:00
Ludovic Marcotte ea43f4a635 Comment improvement 2014-11-12 15:05:05 -05:00
Ludovic Marcotte d25fe1a58b Dramatically improved BSON deserialization speed by avoiding tz name lookups 2014-11-12 14:57:54 -05:00
Ludovic Marcotte 8e1dc0ecb0 Typo in previous commit 2014-11-12 12:56:34 -05:00
Ludovic Marcotte 715999edc8 Avoid compilation failures on non-RHEL 7 distros 2014-11-12 12:54:07 -05:00
Ludovic Marcotte c159d5461b disable rpm-check-build for now 2014-11-12 10:02:04 -05:00
Ludovic Marcotte 5284b57340 More EL7 fixes 2014-11-10 16:19:10 -05:00
Ludovic Marcotte d8e6447fcc More disable lasso 2014-11-10 16:17:06 -05:00
Ludovic Marcotte cb8b0b028e Disable lasso for RHEL7 for now 2014-11-10 16:15:05 -05:00
Francis Lachapelle df648c9204 Add 'zip' to packages dependencies
Fixes #2963
2014-11-10 13:51:38 -05:00
Ludovic Marcotte 624af1c0fb Fixed test 2014-11-10 08:58:30 -05:00
Ludovic Marcotte 395a8ddcfe Updated once more the tz and added missing zones 2014-11-07 10:36:11 -05:00
Ludovic Marcotte 8cd72a8fda Fix borken ORGANIZER fields during the PUT action 2014-11-07 10:06:53 -05:00
Ludovic Marcotte 11a4c1358d Fixed corrupted PNG files (#2975) 2014-11-06 11:23:34 -05:00
Ludovic Marcotte 54d8aa8887 Added new zone files 2014-11-06 11:10:31 -05:00
Ludovic Marcotte 49da494260 Fix for bug #2968 2014-11-06 11:09:16 -05:00
Ludovic Marcotte e08dd3f9eb Fix for bug #2978 2014-11-06 10:16:47 -05:00
Ludovic Marcotte 6de70e4043 sanitize strings before encoding them when using EAS 2014-11-06 09:35:58 -05:00
Francis Lachapelle 7052daa1c8 Fix rename of subscribed addressbooks 2014-11-05 10:05:25 -05:00
Francis Lachapelle 15be4861b6 Fix support for SieveFolderEncoding default
Fixes #2622
2014-11-05 08:44:52 -05:00
Ludovic Marcotte 4b9958336c Handle base64-encoded command parameters in EAS 2014-11-04 13:50:10 -05:00
Ludovic Marcotte 52fdcc34de Fixed typo 2014-10-31 06:46:03 -04:00
Ludovic Marcotte 08427e0bfb set userTimeZone if event has no tz 2014-10-30 18:58:52 -04:00
Ludovic Marcotte d76a4361a0 Added one more sanitization pass on decoded content 2014-10-30 09:20:21 -04:00
Ludovic Marcotte 70cd24e111 Fix for bug #2965 2014-10-29 16:42:52 -04:00
Ludovic Marcotte b5023eeb24 Fix for bug #2940 2014-10-29 14:56:03 -04:00
Ludovic Marcotte da962aed01 Added support for multiple calendars/addressbooks over ActiveSync 2014-10-29 14:20:03 -04:00
Ludovic Marcotte 395545ca51 WP fails to sync if an event is changed on the sever and the client sends a modification of another event 2014-10-29 11:13:18 -04:00
Ludovic Marcotte b53c726766 TZ fixes on WP devices all day events 2014-10-29 10:46:45 -04:00
Francis Lachapelle 6695aa083f Fix crash when opening a mailbox with empty filter
Fixes #2959
2014-10-17 15:22:38 -04:00
Ludovic Marcotte 42ef0bfc3f Added doc around IMAP word size vs. ActiveSync on large mail folders 2014-10-16 11:49:07 -04:00
Ludovic Marcotte fb95d84a3a Handle base64 encoded query strings, popular on Windows devices 2014-10-16 09:35:15 -04:00
Ludovic Marcotte 231987242b Handle empty Attendees tag 2014-10-16 09:10:54 -04:00
Ludovic Marcotte b4f7ec3708 Don't send empty <Responses> tag 2014-10-16 09:08:50 -04:00
Ludovic Marcotte b2cab02d70 Handle empty categories 2014-10-16 09:03:34 -04:00
Ludovic Marcotte d6ff9038ce Disable timezone in AS for now 2014-10-16 09:02:18 -04:00
Ludovic Marcotte c43ad37850 Disable OpenChange for now on RHEL 7 2014-10-15 15:21:20 -04:00
Ludovic Marcotte 096a0ef8e4 Disabled openchange builds on all i386 arch 2014-10-15 11:35:59 -04:00
Francis Lachapelle e2136e0413 Don't leak database passwords in the logs
Fixes #2953
2014-10-14 12:54:04 -04:00
Ludovic Marcotte 3264458f4b Added back -L directives to properly compile teststrings 2014-10-14 11:27:08 -04:00
Alexandre Cloutier 0327a42c9c Update NEWS file 2014-10-14 10:45:30 -04:00
Ludovic Marcotte 5f811e1a4e Added rpath for integration tests 2014-10-14 10:43:52 -04:00
Alexandre Cloutier 923aa5d9b6 bugfix #2952, default sorting for new user 2014-10-14 10:31:11 -04:00
Ludovic Marcotte 3416bfea94 Adjusted rpath and removed unusued -L directives 2014-10-14 10:00:05 -04:00
Ludovic Marcotte f663950808 Adjusted the rpath, removed unnecessary variables/values 2014-10-14 09:51:04 -04:00
Ludovic Marcotte ccabd93ff2 moved system lib dirs to additional lib dirs 2014-10-14 09:21:12 -04:00
Ludovic Marcotte c5a7bcf2aa Fixed the system lib dir to point to the sogo lib dir 2014-10-14 09:17:00 -04:00
Ludovic Marcotte 81ff6bebfe Removed dependancies when openchange is disabled 2014-10-14 09:02:15 -04:00
Ludovic Marcotte 1a8aa5a587 Fixed spec file to not build sogo-openchange if disabled 2014-10-14 09:00:14 -04:00
Ludovic Marcotte 4b76e2b933 Added lib64 in the search path 2014-10-14 08:43:28 -04:00
Francis Lachapelle 27ac9e3904 Cleanup of unused parameters 2014-10-09 15:51:30 -04:00
Francis Lachapelle f8a371e351 Fix folder's name when subscribing to a folder 2014-10-09 15:12:24 -04:00
Francis Lachapelle 460ed2e7bc Fix JavaScript warning on undefined variable 2014-10-09 15:11:06 -04:00
Francis Lachapelle 6cc8f17c86 Fix display name of subscribed folders 2014-10-09 15:10:20 -04:00
Ludovic Marcotte ff9d49be71 Dropped rpath since it seems to be ignored on el5 2014-10-08 10:25:46 -04:00
Ludovic Marcotte f1919d10ed Flag for conditional openchange build 2014-10-08 09:35:50 -04:00
Ludovic Marcotte 3e2de9701c Fixes 2014-10-08 09:29:08 -04:00
Ludovic Marcotte 435ebb9eb4 Fixes 2014-10-08 09:25:40 -04:00
Ludovic Marcotte ab9ba66b36 More fixes 2014-10-08 09:22:14 -04:00
Ludovic Marcotte 29295f93c5 Fixed again the spec file 2014-10-08 09:17:26 -04:00
Ludovic Marcotte 20e0cd6234 Fixed RHEL packaging with lib move to "sogo" app directory 2014-10-08 09:10:02 -04:00
extrafu 2208d5d4a7 Merge pull request #58 from JensErat/SOGo-asciidoc
Minor documentation issues and missing IMAP pooling option description
2014-10-08 07:37:44 -04:00
Jens Erat 25f68c7eb5 Added missing NGImap4DisableIMAP4Pooling option to documentation 2014-10-08 10:07:48 +02:00
Jens Erat 22844a5742 Minor fixes in documentation 2014-10-08 10:01:17 +02:00
Ludovic Marcotte e3837188fd Updated spec file for SOGo's private libraries move 2014-10-06 14:45:30 -04:00
Francis Lachapelle a0317046ba Card view: don't escape <br>'s in note field 2014-10-06 08:42:59 -04:00
extrafu f353b6d1c0 Merge pull request #57 from dekkers/make-png-non-executable
Make png files non-executable
2014-10-05 09:58:29 -04:00
Jeroen Dekkers 4cc6b72cfb Make png files non-executable 2014-10-05 15:47:00 +02:00
Francis Lachapelle d7f8427623 Improve XSL for documentation 2014-10-03 13:13:42 -04:00
Ludovic Marcotte 7f49dcb2fa Avoid using SOGO_SYSLIBDIR when testing since it's undefined 2014-10-02 13:10:54 -04:00
Ludovic Marcotte f29a47d443 Added rpath 2014-10-02 12:42:06 -04:00
Ludovic Marcotte f88cfae611 Improved and simplified rpath 2014-10-02 12:36:22 -04:00
Ludovic Marcotte fb3ddca9e8 Improved makefiles 2014-10-02 11:17:45 -04:00
Ludovic Marcotte ba4a50e778 Added rpath kungfu 2014-10-02 11:05:19 -04:00
Ludovic Marcotte 8875c42d25 Fixed makefile 2014-10-02 11:00:43 -04:00
Ludovic Marcotte 18431922ab Fixed makefile 2014-10-02 10:55:05 -04:00
Ludovic Marcotte f93c06e6a9 Fixed include 2014-10-02 10:50:34 -04:00
Ludovic Marcotte 68d79472a5 Fixed makefile for teststrings due to sogo lib change 2014-10-02 10:46:47 -04:00
Ludovic Marcotte 51ed371796 Adjusted debian install files regarding sogo lib move 2014-10-02 10:21:36 -04:00
extrafu 641b6a3174 Merge pull request #3 from dekkers/put-private-library-in-usr-lib-sogo
Put private SOGo libraries in /usr/lib/sogo
2014-10-01 14:39:18 -04:00
Jeroen Dekkers 6ded9e95b3 Put private libraries in /usr/lib/sogo 2014-10-01 20:36:42 +02:00
Ludovic Marcotte 25b7fffb00 Fix for bug #2930 2014-10-01 14:08:29 -04:00
Francis Lachapelle 89284d558c Add missing translation 2014-10-01 09:02:03 -04:00
Ludovic Marcotte 9610fcc5ca Bumped version 2014-09-29 15:30:02 -04:00
Ludovic Marcotte 9cdcfd1d4a Updated for the 2.2.9a release 2014-09-29 15:29:49 -04:00
Ludovic Marcotte 95b122c912 Simplified even more -safeString 2014-09-29 15:04:40 -04:00
Ludovic Marcotte aa0499dbac Fixed sanitization char skipping and #2936 2014-09-29 14:28:13 -04:00
extrafu a263939d8a Merge pull request #49 from Zentyal/Contrib
Several patches for the OpenChange integration
2014-09-29 09:07:36 -04:00
Francis Lachapelle 80acafadd3 Fix URL in documentation 2014-09-26 14:49:36 -04:00
Ludovic Marcotte 4c5be2fd97 Update ChangeLog 2014-09-26 14:31:57 -04:00
Ludovic Marcotte a5af5da259 Merge branch 'master' of https://github.com/inverse-inc/sogo 2014-09-26 14:30:30 -04:00
Ludovic Marcotte c0e8eb6ce3 Adjusted the doc for TB31 2014-09-26 14:29:20 -04:00
Francis Lachapelle 4be2ddb793 Update translations 2014-09-26 14:23:58 -04:00
Ludovic Marcotte 5744d18474 Updated scripts for TB31 2014-09-26 14:15:32 -04:00
Francis Lachapelle 9e1423cd4a New font for asciidoc documentation
We now use Lato.
2014-09-26 14:14:54 -04:00
Ludovic Marcotte 275eebde0f Updated NEWS file for the release 2014-09-26 10:53:01 -04:00
Ludovic Marcotte 0b6e3dc22d Fix for bug #589 2014-09-25 09:25:13 -04:00
Ludovic Marcotte 3675220756 Refactored code to be more rigorous Unicode-wise. 2014-09-24 14:14:25 -04:00
Ludovic Marcotte 1c60ab2337 Fix for bug #2889 2014-09-24 12:02:12 -04:00
Ludovic Marcotte f4372af16d Add over DAV a PARTSTAT if none is defined 2014-09-23 13:46:44 -04:00
Ludovic Marcotte 6ba85ee43a Added some comments in the code 2014-09-22 11:38:07 -04:00
Ludovic Marcotte ae6afedc92 Fixed potential exception when Calendar module is disabled 2014-09-22 08:38:01 -04:00
Ludovic Marcotte d572f2af02 get rid of control chars before returning the response 2014-09-19 14:34:20 -04:00
Ludovic Marcotte a338b193ba Fix for bug #2838 2014-09-17 19:45:44 -04:00
Ludovic Marcotte 11adf388cf Cleaned the code and fixed #2894 while at it ... 2014-09-17 11:51:46 -04:00
Ludovic Marcotte a4ab2942e8 Fix for bugs #2878, #2879 2014-09-17 11:35:09 -04:00
Francis Lachapelle 7e281dca99 Fix encoding of calendar names in Web interface 2014-09-17 09:45:44 -04:00
Ludovic Marcotte ce1896b627 Fixed typo 2014-09-17 09:36:35 -04:00
Ludovic Marcotte f52a083326 fixed sending mails to multiple recipients over AS 2014-09-17 09:34:36 -04:00
Ludovic Marcotte 8ba031d6ec Consider 0x0C as "unsafe" 2014-09-15 19:54:07 -04:00
Ludovic Marcotte c5c2bfb7a6 Fixed iCal detection for 10.9 (and perhaps even 10.8) 2014-09-15 14:10:05 -04:00
Alexandre Cloutier 6ec79f7792 bugfix with threads collapsing for a nested folder 2014-09-15 10:38:02 -04:00
Francis Lachapelle 4b9db66f8b Fix warning when generating docbook 2014-09-15 10:33:44 -04:00
Ludovic Marcotte 02b3de6465 Fix for bug #2326 2014-09-15 09:32:36 -04:00
extrafu e0fee3b0e0 Merge pull request #56 from JensErat/SOGo-asciidoc
Converted documentation to ASCIIdoc
2014-09-15 09:08:25 -04:00
Jens Erat 4b49fc33b2 Updated for 2.2.8 2014-09-15 02:48:44 +02:00
Jens Erat 19b313e6c4 Updated some copyright lines from PacketFence to SOGo 2014-09-15 02:48:44 +02:00
Jens Erat 397d8d7574 Remove old documentation files 2014-09-15 02:48:44 +02:00
Jens Erat 8a564975c8 Added makefile for asciidoc-conversion, included docbook-templates 2014-09-15 02:47:36 +02:00
Jens Erat 95191cb29b Added other documentation files as asciidoc 2014-09-15 02:47:36 +02:00
Jens Erat 8d4c0ff694 Converted Installation Guide to asciidoc 2014-09-15 02:47:36 +02:00
Ludovic Marcotte 8b4a16df4e NEWS entry for previous commit 2014-09-12 14:10:22 -04:00
Ludovic Marcotte b8b3519a40 Initial support for multiple alarms and better iCal compatibility 2014-09-12 14:09:28 -04:00
Ludovic Marcotte 12a4fd05a2 Support for repetitive alarms and tasks 2014-09-12 08:34:15 -04:00
extrafu 8cdaac6300 Merge pull request #35 from dekkers/link-libraries-correctly
Link correctly against libraries used
2014-09-11 21:02:08 -04:00
extrafu 0e21904c03 Merge pull request #10 from dekkers/link-libsogo-with-libdl
Link libSOGo with libdl on systems with glibc
2014-09-11 21:01:30 -04:00
extrafu 496fa73d36 Merge pull request #26 from Skrupellos/master
ModulesConstraints tests all values of a multi-valued attributes
2014-09-11 16:09:06 -04:00
Francis Lachapelle 0825a810e3 Add missing localization string 2014-09-11 11:58:39 -04:00
Francis Lachapelle ed85a09ff0 Allow alarms to be snoozed for 1 day 2014-09-11 11:55:20 -04:00
Ludovic Marcotte 38cb86bdb1 Update ChangeLog 2014-09-10 14:15:34 -04:00
Alexandre Cloutier 69c8aa0743 quickfix for IE for searchInbox 2014-09-10 13:22:36 -04:00
Alexandre Cloutier 60e3c1c822 Merge branch 'master' of https://github.com/inverse-inc/sogo 2014-09-10 13:02:45 -04:00
Alexandre Cloutier 36b833ccb5 bugFix InboxSearch IMAP query keywords 2014-09-10 13:02:13 -04:00
Francis Lachapelle 9d6bcb00bc Fix compilation warning 2014-09-10 11:58:47 -04:00
Francis Lachapelle 1dd3dbacb5 Various fixes and improvements to the Mail module 2014-09-10 11:37:52 -04:00
Francis Lachapelle c441fa5b80 Various fix and improvements to Scheduler module 2014-09-10 10:58:58 -04:00
Francis Lachapelle 7e297ad56c Remove spaces 2014-09-10 10:58:46 -04:00
Francis Lachapelle 8eb4212f5d Various fix and improvements to Mail module 2014-09-10 10:49:54 -04:00
Luc Charland 3ad9327d17 putting test-prevent-invitations back in 2014-09-10 10:25:42 -04:00
Ludovic Marcotte 0483794f45 Updated the documentation for the release 2014-09-10 09:20:47 -04:00
Alexandre Cloutier 3c1d6d7d89 bugfix; UserSettings was not refresh properly after toggling threads 2014-09-09 16:05:12 -04:00
Francis Lachapelle 1dcf631ad6 Update translations 2014-09-09 15:50:39 -04:00
Ludovic Marcotte cbc53b3a52 Updated NEWS file 2014-09-09 15:38:15 -04:00
Alexandre Cloutier 574c245758 bugfix PreventInvitation; fix object parsing on a blank user 2014-09-09 15:36:14 -04:00
Alexandre Cloutier f3ca4ea7fc bugfix foldingThread; Renaming a foldername with a space was not correctly handled 2014-09-09 15:36:14 -04:00
Ludovic Marcotte e542ff5646 Fix for bug #1240 2014-09-09 15:15:56 -04:00
Francis Lachapelle bbe1e09ab9 Merge pull request #52 from alexcloutier/feature/RefreshViewCheck
All modules can now be automatically refreshed
2014-09-09 15:12:21 -04:00
Alexandre Cloutier 9daab5a9a1 update NEWS file 2014-09-09 14:28:05 -04:00
Alexandre Cloutier 1fb3198dbc applied comments 2014-09-09 14:27:05 -04:00
Alexandre Cloutier d62c504763 Changed the configurable variable SOGoMailMessageCheck to a general refresh associated to the current view 2014-09-09 14:27:05 -04:00
extrafu 126a05d391 Merge pull request #54 from alexcloutier/feature/FoldingThreads
Feature/folding threads
2014-09-09 14:06:30 -04:00
extrafu 42ffe14052 Merge pull request #55 from alexcloutier/bugfix/LabelsTagging
Bugfix/labels tagging
2014-09-09 14:06:19 -04:00
Alexandre Cloutier 7db526a5d9 bugfix for new user without userSettings.mail 2014-09-09 13:51:02 -04:00
Alexandre Cloutier 06f81a032c applied comments 2014-09-09 13:51:02 -04:00
Alexandre Cloutier df42c31618 Update NEWS file 2014-09-09 13:51:02 -04:00
Alexandre Cloutier e6002c9b2a applied comments 2014-09-09 13:51:02 -04:00
Alexandre Cloutier 0c88edc61b bugfix where an exception was raised if threadsCollapsed is undefined 2014-09-09 13:51:02 -04:00
Alexandre Cloutier 267a689683 Applied comments 2014-09-09 13:51:02 -04:00
Alexandre Cloutier c9d1294a8a Manage the collapse UIDs save in the user settings 2014-09-09 13:51:02 -04:00
Alexandre Cloutier 59023da7f0 applied comments and fix bug where the folded threads were saved only after refreshing the entire page 2014-09-09 13:51:02 -04:00
Alexandre Cloutier c5f9dd086b Possibility to collapsed threads with persistance 2014-09-09 13:51:02 -04:00
Alexandre Cloutier 0bfaceb398 applied comments 2014-09-09 12:51:59 -04:00
Alexandre Cloutier 9a380f711c bugfix PreventInvitation 2014-09-09 11:30:00 -04:00
Ludovic Marcotte 8c8e7d24a7 Modified Apache's config file to handle Apache > 2.3 2014-09-08 15:25:21 -04:00
Alexandre Cloutier 77c50e5232 applied comments; fix errors from merge and update NEWS file 2014-09-08 14:11:42 -04:00
Francis Lachapelle 56ef00661c Merge pull request #50 from alexcloutier/feature/SearchInbox
New feature to search multiple mailboxes
2014-09-05 16:09:59 -04:00
Francis Lachapelle b639c2d251 Fixes for IE 2014-09-05 16:04:29 -04:00
Alexandre Cloutier 984e208dd9 IE bugfixes 2014-09-05 11:01:57 -04:00
Luc Charland 606ee9780e dont test prevent invitations 2014-09-04 22:36:02 -04:00
Luc Charland c6f82dac01 catch specific exception 2014-09-04 22:24:32 -04:00
Luc Charland e37a603632 should help some builds that might timeout 2014-09-04 21:59:36 -04:00
Alexandre Cloutier ca8351d1f9 fix IE7, IE8, IE9, IE10, IE11 GUI 2014-09-04 10:50:03 -04:00
Luc Charland 031e4c9409 more of the same 2014-09-03 22:43:49 -04:00
Luc Charland c621bbcd56 Those need the same adjustments 2014-09-03 22:32:46 -04:00
Luc Charland 4b94a183be urllib.quote needs a string 2014-09-03 13:50:13 -04:00
Alexandre Cloutier 32476b16cc applied comments and fix bug when tagging msgs already tagged 2014-09-02 14:31:46 -04:00
Alexandre Cloutier 3b65eaea0b Tagging labels with 1 AJAX request 2014-09-02 13:42:04 -04:00
Alexandre Cloutier 7e26d80c77 merge conflicts 2014-09-02 10:11:27 -04:00
Francis Lachapelle 1af52e6d6b Fix message labels handling
Selecting "none" from the label submenu on a multiple selection of
messages is now working. When changing the label of multiple messages,
the display is now properly updated.

Fixes #2902
2014-08-29 15:39:06 -04:00
Alexandre Cloutier eaf815eae6 update NEWS file 2014-08-29 14:55:21 -04:00
Alexandre Cloutier 9bd09cc55d add the location column 2014-08-28 13:20:43 -04:00
Luc Charland ced0962894 Added white_listed_attendee to the config file 2014-08-28 10:43:32 -04:00
Francis Lachapelle dadad3df2a Fix some compilation warnings 2014-08-28 09:38:09 -04:00
Alexandre Cloutier da184f8459 bugfix#2864 2014-08-27 16:50:45 -04:00
Alexandre Cloutier 03152ea3d4 bugfix with DND from calendar view to calendar list 2014-08-27 16:01:35 -04:00
Alexandre Cloutier 8fbd2384a4 Merge branch 'master' of https://github.com/inverse-inc/sogo 2014-08-27 13:55:02 -04:00
Alexandre Cloutier 84a08659ec bugfix where it is not possible to delete msg when mailbox is full 2014-08-27 13:50:56 -04:00
Luc Charland d749d5c2fb Added tests for prevent invitation and whitelist 2014-08-27 13:31:49 -04:00
Alexandre Cloutier 07a138e0d6 applied comments and add the possibility to resize the search inbox window 2014-08-27 12:30:33 -04:00
Alexandre Cloutier 76c9b45fd0 update Localizable.strings
Update the print window options strings
2014-08-26 14:25:27 -04:00
Alexandre Cloutier 1ab3a588f3 Merge branch 'master' of https://github.com/inverse-inc/sogo 2014-08-26 13:41:58 -04:00
Alexandre Cloutier 38a3b7bb4f print calendars events&Tasks with colors - either borders or backgrounds 2014-08-26 13:36:42 -04:00
Francis Lachapelle b2b77c65d3 Fix folders paths of "sogo-tool restore -l" 2014-08-26 09:00:13 -04:00
Alexandre Cloutier 6aecccf6ca indentations 2014-08-25 13:46:35 -04:00
Francis Lachapelle e4a84d4920 Fix usage of SOGoSubscriptionFolderFormat default 2014-08-25 12:15:05 -04:00
Francis Lachapelle 28f26ec08e Fix display of users with no possible subscription 2014-08-25 10:16:10 -04:00
Francis Lachapelle 74bd96e5a6 Fix encoding of new calendars + new subscriptions 2014-08-25 10:12:09 -04:00
Alexandre Cloutier e044476772 bugFix #2827 2014-08-15 13:41:30 -04:00
Alexandre Cloutier c76cb36461 Disable the search button on toolbar once it is opened 2014-08-15 13:06:46 -04:00
Alexandre Cloutier 73fcdc2306 adjust css for other browser, fix display bug 2014-08-15 11:41:37 -04:00
Ludovic Marcotte b9dd1ddc5a Fix for bug #2892 2014-08-15 09:57:19 -04:00
Alexandre Cloutier 8783f09a4a fix leak 2014-08-14 15:01:40 -04:00
Alexandre Cloutier 52476251b8 applied comments, fix bug and add sortable results 2014-08-14 14:49:44 -04:00
Alexandre Cloutier f6c7ca3379 applied comments 2014-08-13 17:41:58 -04:00
Alexandre Cloutier c3e46e4baf code refactoring and GUI improvement 2014-08-11 09:25:09 -04:00
Alexandre Cloutier 7794d716b9 version 1 of the inbox search 2014-08-06 14:49:36 -04:00
Francis Lachapelle 5b886e5c4d Fix issue with DnD of tasks with FireFox 2014-08-01 12:26:53 -04:00
Jesús García Sáez 1a2fe8908b Revert "Merge pull request #2 from Zentyal/jgarcia/fix-encoding-of-mapistoreuris" 2014-08-01 15:50:17 +02:00
Ludovic Marcotte cde1db9324 Refactored GCSFolder: -writeContent and fixed sogo-tool restore 2014-08-01 09:40:45 -04:00
Ludovic Marcotte f43341c100 Fixed JSON'ification of the admin module 2014-07-31 16:19:49 -04:00
Ludovic Marcotte b05fcc7d82 Fat commit to refactor the quick record generation 2014-07-30 14:51:00 -04:00
Francis Lachapelle 07324e56a0 Update ChangeLog 2014-07-30 11:16:35 -04:00
Francis Lachapelle 397a36cc89 Preparation for release 2.2.7 2014-07-30 11:16:10 -04:00
Francis Lachapelle c240931c54 Update CKEditor to version 4.4.3 2014-07-30 11:15:05 -04:00
Francis Lachapelle ef2432e10f Update NEWS file 2014-07-30 10:36:31 -04:00
Francis Lachapelle 571322958a Update fi, fr, de, and es_ES translations 2014-07-30 10:33:15 -04:00
Francis Lachapelle bd5c05cca2 Indentation in JavaScript files 2014-07-30 10:31:25 -04:00
Francis Lachapelle ea44308aa3 Fix all-day events display in IE
It also fixes the display of the event categories for all-day events in
IE.
2014-07-29 16:05:46 -04:00
Carlos Pérez-Aradros Herce f76a6cfc96 Fix mysql cleanup log message 2014-07-29 18:27:20 +02:00
Kamen Mazdrashki 2b3bc10f78 Scripts/openchange_user_cleanup: Don't hardcode samba private dir, use samba LoadParm()
Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-29 18:26:30 +02:00
Jesús García Sáez 3eba5f940e increase log level of debug message 2014-07-29 18:25:46 +02:00
Jesús García Sáez 7f2ee7be89 Error message only when initialization hadn't been done
In a multithread environment, sogo_backend_init is registering the thread
only for the first one that calls this function, then the others threads
(even if they call sogo_backend_init) won't be registered because
moduleInitialized was YES.

We just want to ensure sogo_backend_init is called at least once (per process,
not per thread).
2014-07-29 18:25:28 +02:00
Miguel Julián 41f2e917e7 Removed development tip comment 2014-07-29 18:22:34 +02:00
Miguel Julián 65ece61273 Removing some trail characters at event description
* They are sometimes present after a \r\n\n
2014-07-29 18:22:32 +02:00
Ludovic Marcotte 94f3246658 Improved error message when you cannot invite users 2014-07-29 10:36:20 -04:00
Ludovic Marcotte 1df7e989e0 Removed worthless declaration 2014-07-25 14:48:25 -04:00
Francis Lachapelle d9ca1051b3 Improve headers of multicolumns view 2014-07-25 11:34:33 -04:00
Ludovic Marcotte 4eefa4c269 Fixed test since we now return a 200 instead of a 204 2014-07-25 08:12:12 -04:00
Ludovic Marcotte 4c21a050d9 JSON interface to folder subscriptions 2014-07-24 14:00:57 -04:00
Alexandre Cloutier b52289904f task.png for DnD taskList 2014-07-24 13:48:41 -04:00
Alexandre Cloutier d5b71526ed Merge branch 'master' of https://github.com/inverse-inc/sogo 2014-07-24 13:44:02 -04:00
Alexandre Cloutier c389630d76 DnD tasksList 2014-07-24 13:35:14 -04:00
Ludovic Marcotte f6ef94a631 improved handling of SOGoSubscriptionFolderFormat 2014-07-24 12:48:03 -04:00
Francis Lachapelle 5de51e8aa1 Fix missing argument with new DnD controller 2014-07-24 09:30:19 -04:00
Ludovic Marcotte 006727a74b Properly destroy cache objects of vanished folders 2014-07-24 08:39:41 -04:00
extrafu 037dd67635 Merge pull request #47 from dekkers/mailpartviewers-requires
Add Mailer and Appointments to product.list requires of MailPartViewers
2014-07-22 14:00:35 -04:00
Jeroen Dekkers 6619840f80 Add Mailer and Appointments to product.list requires of MailPartViewers 2014-07-22 19:54:18 +02:00
Francis Lachapelle 08fd2fcfaa Fix JavaScript after bad merge 2014-07-22 13:26:28 -04:00
Alexandre Cloutier a43dd97fc9 Fix bug with DnD; leftPanelController.stopEvent() 2014-07-22 11:37:45 -04:00
Francis Lachapelle 192659fdd9 Add missing localizable string 2014-07-21 16:12:27 -04:00
Francis Lachapelle 06fe36fd75 Add missing localizable strings 2014-07-21 16:07:13 -04:00
Francis Lachapelle 24f9d83ff7 Fix JavaScript from merge leftover 2014-07-21 16:06:24 -04:00
Ludovic Marcotte 8dd967d0a8 Updated NEWS file for two merged pull requests 2014-07-21 15:38:23 -04:00
Ludovic Marcotte 08cd080d47 Fixed charset substitution in meta tags 2014-07-21 15:34:56 -04:00
Francis Lachapelle 11920f592c Merge pull request #46 from alexcloutier/feature/DragNDropCalendars
Improve drag'n'drop of events in multi-column view
2014-07-21 11:00:27 -04:00
Alexandre Cloutier 28e6bb8b9d Applied comments 2014-07-21 09:52:09 -04:00
Alexandre Cloutier b892b3f794 Add RegEx 2014-07-21 09:52:09 -04:00
Alexandre Cloutier cdf4cc1acb fix DnD from eventList to calendarList for repeated event 2014-07-21 09:52:08 -04:00
Alexandre Cloutier 3cac794de5 move line 2014-07-21 09:52:08 -04:00
Alexandre Cloutier 8f9b24a23f visual helper while dragging from calendar view to calendarList 2014-07-21 09:52:08 -04:00
Alexandre Cloutier a2a7014140 fix dnd repeated event bug + applied comments 2014-07-21 09:52:08 -04:00
Alexandre Cloutier a5ecb2063f added event7.png and adjust javascript indentation 2014-07-21 09:52:08 -04:00
Alexandre Cloutier 9bd7aeebfb DnD from calendarView to CalendarList 2014-07-21 09:40:04 -04:00
Alexandre Cloutier 01af72cfe9 DnD from eventList to the calendarList 2014-07-21 09:40:04 -04:00
Alexandre Cloutier 6dddb5c98c dragNdrop from the events table to the calendars list 2014-07-21 09:40:04 -04:00
Alexandre Cloutier ccf181bcf9 applied comments and fix repeated events dragNdrop between calendars 2014-07-21 09:40:04 -04:00
Alexandre Cloutier e478b29c2e creating and dragNDrop between calendars in multicolumndayview 2014-07-21 09:40:04 -04:00
Francis Lachapelle f3ded6ce2a Merge pull request #45 from alexcloutier/feature/PreventInvitations
New user preference to prevent invitations
2014-07-21 09:38:42 -04:00
Alexandre Cloutier c2027f072d indentation 2014-07-21 09:29:00 -04:00
Alexandre Cloutier ce6a31dd38 Adjust line of code to make it easier to read 2014-07-21 09:27:02 -04:00
Alexandre Cloutier a71013eebf javascript indentation 2014-07-21 09:27:02 -04:00
Alexandre Cloutier eaec5a614d Change exception 403 to 409 and fix indentation in the javascript 2014-07-21 09:27:02 -04:00
Alexandre Cloutier 5217bed5ae Organized the categories and appointments invitations inside a tabContainer 2014-07-21 09:27:02 -04:00
Alexandre Cloutier 17319cc8dd reverted UIxListEditor.wox 2014-07-21 09:27:02 -04:00
Alexandre Cloutier 89d116363c replace ampersands with commas 2014-07-21 09:27:02 -04:00
Alexandre Cloutier 7c3e85f517 applied comments 2014-07-21 09:27:02 -04:00
Alexandre Cloutier 05fb7ae0c8 applied comments 2014-07-21 09:27:02 -04:00
Alexandre Cloutier ef20108e32 fix bug where the user could enter any names in the whitelist 2014-07-21 09:27:02 -04:00
Alexandre Cloutier b5c0363400 applied comment and refactor code 2014-07-21 09:27:02 -04:00
Alexandre Cloutier f0b8eb8dfb server side code to integrate the whitelist 2014-07-21 09:27:02 -04:00
Alexandre Cloutier 16d02455bd Serialization of the whiteList 2014-07-21 09:27:02 -04:00
Alexandre Cloutier 8ded5a8aaf Prevent Invitations and whitelist GUI 2014-07-21 09:27:02 -04:00
Ludovic Marcotte 1cc93c700a Updated NEWS file for changes occurred right after v2.2.6 was released 2014-07-09 14:08:31 -04:00
Francis Lachapelle 44d0cb5c0d Fix refresh of list when forwarding a message
Fixes #2818
2014-07-09 11:19:35 -04:00
Ludovic Marcotte dbdb7d9051 Fix sending of METHOD:REPLY for DAV clients 2014-07-09 10:04:44 -04:00
Francis Lachapelle e343ed240b Fix regression of word breaking
Fixes #2845
2014-07-08 22:01:41 -04:00
Francis Lachapelle 45553be122 Fix rename of calendars, improve tasks count badge 2014-07-08 17:19:55 -04:00
Alexandre Cloutier 1cf4841477 fix display glitch 2014-07-04 11:23:59 -04:00
Alexandre Cloutier 017a85b7f2 fix month events categories display 2014-07-04 10:46:49 -04:00
Alexandre Cloutier 103bb6803a Merge branch 'master' of https://github.com/inverse-inc/sogo 2014-07-04 10:38:24 -04:00
Alexandre Cloutier 8c8e47daf6 fix spacing between events and categorie display 2014-07-04 10:37:35 -04:00
Ludovic Marcotte 8a17246725 Cleaned up code and fixed the translation of the weekdays in the datepicker 2014-07-04 10:18:56 -04:00
Ludovic Marcotte 4843c6b6d7 Renamed Multi-Column to Multicolumn and refactored some code 2014-07-04 08:55:35 -04:00
Ludovic Marcotte 6e13f15477 Update ChangeLog 2014-07-02 11:32:18 -04:00
Ludovic Marcotte 5dd2088d42 Updated for the release 2014-07-02 11:32:06 -04:00
Ludovic Marcotte 9c3c2cb926 Updated the doc for the release 2014-07-02 11:23:57 -04:00
Ludovic Marcotte 55422b5f03 Fixed typo 2014-07-02 10:11:13 -04:00
Kamen Mazdrashki 1846e1ee5d oc/TallocWrapper: don't handle Threading initialization here
It is SOGo backend module responsibility to setup/teardonw all
ObjC specific initialization

Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 15:20:51 +02:00
Kamen Mazdrashki 1fc3a57210 oc: Protect backend initialization to happen only once 2014-07-02 15:20:31 +02:00
Kamen Mazdrashki 5b75c817e2 oc: Log when mapistore backend is successfully initialized 2014-07-02 15:20:19 +02:00
Kamen Mazdrashki c91741ad1f oc/dbmsgreader: Fix to work again this time basen on BSON format for msg data
Also, implement reading for message data in case only 1 param is passed.
This could be usefull when have msg data by other means than by
reading it directly from DB

Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 15:19:59 +02:00
Kamen Mazdrashki 86e54989fb oc/utils: Make "plext" category publicly visible
Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 15:19:47 +02:00
Kamen Mazdrashki 116e738e63 oc/utils: Move OCDumpPListData() function into plreader - this is the only user for this function
Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 15:19:31 +02:00
Kamen Mazdrashki bf0f2a76d5 oc/MAPIStoreSOGo: Do not destroy current thread context after any API call
We have thread context already in place during *_init() function.
Thus guarding every API call with TreadInit/Destroy is:
- a bit redundand
- makes SOGo backend not reentrant even on single thread and leads
  to hard to find use-after-free crashes

Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 15:19:19 +02:00
Kamen Mazdrashki 6de298d202 oc/MAPIStoreMapping: Split the check for existing entry so we have better error message
Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 15:18:49 +02:00
Kamen Mazdrashki 98505c1b6b oc/MAPIStoreContext: Fix log messages to actually print 64bit FMIDs
Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>

Conflicts:
	OpenChange/MAPIStoreContext.m
2014-07-02 15:18:33 +02:00
Miguel Julián 51df0adb79 Removed development tip comment 2014-07-02 15:00:24 +02:00
Miguel Julián 5d43513dd9 Removing some trail characters at event description
* They are sometimes present after a \r\n\n
2014-07-02 14:59:16 +02:00
Miguel Julián 2458af1a43 All day events deladyed one day if user timezone is +XX:XX
* Those events were not shown properly in SOGo web UI
2014-07-02 14:59:06 +02:00
Kamen Mazdrashki 2792baac02 openchange: don't overflow possible recipient type while creating message headers
Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 14:58:57 +02:00
Kamen Mazdrashki 4b383705ff openchange: Fix submitWithFlags to submit to BCC-ed recipients also
this reintroduces commit 7efb263c659451d2c781547a5b38cb5d01ed837f

Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 14:58:47 +02:00
Kamen Mazdrashki dd7200e00f openchange/MAPIStoreFolder: Add private selector for actual folder delete action
Usually, it is a bad idea for an object to call its own public methods
(just like in this case). Thus separating impelementation for deleteFolder:
would allow MAPIStoreFolder to call only private implementation when needed

Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 14:58:33 +02:00
Kamen Mazdrashki 27851ef428 openchange: FillMessageHeadersFromProperties fix skipping of last value in
possible range of recepients

IMHO, this fixes a bug, that when saving a meessage, it  is saved
without BCC fields.

Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 14:58:16 +02:00
Kamen Mazdrashki 7da8885190 openchange: getMessageData - replace int literals with ulRecipClass values
Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 14:58:06 +02:00
Kamen Mazdrashki fc9dc08045 oc-sogo: pretty print Exceptions in sogo_backend_handle_objc_exception()
Now we have a nice stack trace printed out from [NSException callStackSymbols]

Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 14:53:34 +02:00
Kamen Mazdrashki bcfb674cd1 oc-sogo: Print both [NSException callStackSymbols] and execinfo.h stack trace
Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 14:53:24 +02:00
Kamen Mazdrashki 6be768af42 oc-sogo: Move memory clean up *after* handling the exception
Otherwise the mess is full :)

Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 14:53:10 +02:00
Kamen Mazdrashki 2c94d21f3e oc-sogo: Use [e name] and [e reason] selectors
Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 14:52:59 +02:00
Kamen Mazdrashki cbe616358d oc-sogo: Clean up AutoRelease pool and unregister threads in Catch handler
Most of the time we have "not yet implemented" kind of exceptions,
so it is better to clean up allocated resources

Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 14:52:34 +02:00
Kamen Mazdrashki 09e6fcc3ff oc-sogo: try/catch to guard only the actual impelementation rather than *everything*
Signed-off-by: Kamen Mazdrashki <kmazdrashki@zentyal.com>
2014-07-02 14:52:20 +02:00
Jesús García Sáez 3b2174eeec if there is no password file for specific user, try to read global password file
This way we can have a master password for imap access
2014-07-02 14:51:08 +02:00
Jesús García Sáez c6b8be742d use execinfo.h to get backtrace
Really poor backtrace because it will only have the frames from oc side,
I don't know why callStackSymbols is returning null, compilation flags?
2014-07-02 14:50:54 +02:00
Jesús García Sáez a77863947f add try catch to all functions on struct mapistore_backend 2014-07-02 14:50:41 +02:00
Jesús García Sáez d1f54298d2 stringByDecodingImap4FolderName is not neccesary
For russian locale and characters nonexistent in latin1 sogo crashes
2014-07-02 14:48:45 +02:00
Kamen Mazdrashki f8028b5a94 OpenChange: Avoid crashing when creating embedded message in attachment
Signed-off-by: Kamen Mazdrashki <kamenim@samba.org>
(cherry picked from commit 15a55f9f707247c9164e8fa7a102639744f686e5)
2014-07-02 14:48:27 +02:00
Jesús García Sáez 6bef678114 fix format logging uint64_t 2014-07-02 14:47:57 +02:00
Jesús García Sáez c81476bd04 no need to modify url 2014-07-02 14:47:45 +02:00
Jesús García Sáez a24f009cfe mapistoreURI encoding should be done the same way as listContextForUser
stringByEncodingImap4FolderName is used inside [newFolder create] where is needed
2014-07-02 14:47:31 +02:00
Jesús García Sáez 95298de9f1 avoid infinite loop when trying to update a folder id 2014-07-02 14:45:52 +02:00
Jesús García Sáez f6d1a37127 use properly get_uri function and check ret value 2014-07-02 14:44:23 +02:00
Jesús García Sáez 2aa71cc8a3 check ret value properly 2014-07-02 14:43:42 +02:00
Jesús García Sáez 34b98a563d get_new_folderID functions are now on mapistore_indexing 2014-07-02 14:42:17 +02:00
Carlos Pérez-Aradros Herce fd308b592f Converted all the indexing code to indexing backends 2014-07-02 14:41:51 +02:00
Carlos Pérez-Aradros Herce a6bfb9d5c5 Use indexing generic code instead of tdb private funtions 2014-07-02 14:41:40 +02:00
Carlos Pérez-Aradros Herce 33b353b974 Moved to abstract index_context instead of tdb_wrap 2014-07-02 14:41:25 +02:00
Ludovic Marcotte 899a1eb026 Updated NEWS file 2014-07-02 08:39:01 -04:00
Alexandre Cloutier 660f39a980 delete notice and put grey background for multi-columns view 2014-06-30 14:13:52 -04:00
Alexandre Cloutier 8335c38830 fix infinite loop bug 2014-06-30 13:57:10 -04:00
Alexandre Cloutier 0fb7135335 bugfixes 2014-06-30 13:36:12 -04:00
extrafu 70b0cb78cd Merge pull request #44 from alexcloutier/fix/DailyViewByCalendars
Fix/daily view by calendars
2014-06-30 11:01:06 -04:00
Alexandre Cloutier d197ab71b7 merging conflicts 2014-06-30 10:55:55 -04:00
Alexandre Cloutier 6b58e034f3 printView display the parentView by default 2014-06-30 10:42:07 -04:00
Ludovic Marcotte ff015afde8 Fixed indent 2014-06-30 10:35:55 -04:00
Ludovic Marcotte 6da03bc75c Cleaned up code for older gcc 2014-06-28 08:31:07 -04:00
Alexandre Cloutier 2b119c63e0 Applied comments 2014-06-27 17:21:18 -04:00
Alexandre Cloutier 5b61df8ca4 activeTasks updates dynamically 2014-06-27 17:00:32 -04:00
Alexandre Cloutier 659e2f3aa8 Merge branch 'master' of https://github.com/inverse-inc/sogo 2014-06-27 10:30:10 -04:00
extrafu 8191576361 Merge pull request #41 from alexcloutier/fix/displayTaskNumber
Display the number of active tasks in calendar view
2014-06-27 09:07:07 -04:00
Alexandre Cloutier 5b9c7e07d1 text wraping and text alignment in list view 2014-06-26 21:22:12 -04:00
Alexandre Cloutier cafb896e8c Merge branch 'fix/displayTaskNumber' of https://github.com/alexcloutier/SOGo into fix/displayTaskNumber 2014-06-26 16:43:10 -04:00
Alexandre Cloutier 7a69bc46eb applied comments 2014-06-26 16:42:05 -04:00
Alexandre Cloutier 302e40a1c3 bugFix#2823 2014-06-26 16:08:47 -04:00
Ludovic Marcotte b6be4e6e2f Applied patch from bug #2810 2014-06-26 11:01:16 -04:00
Alexandre Cloutier dabd8d3282 Fix list view printing with multiColumns view 2014-06-26 10:05:48 -04:00
Alexandre Cloutier d7d458a934 multiColumns print view + bugFixes 2014-06-25 17:39:48 -04:00
Ludovic Marcotte 5419f411e5 Fix for bug #2734 2014-06-25 15:05:25 -04:00
Ludovic Marcotte 22f5ed62fe Fixed tests regarding default permissions on CalDAV collections 2014-06-25 10:14:28 -04:00
Ludovic Marcotte 3523dc489f Fix for bug #2825 2014-06-23 12:19:02 -04:00
Alexandre Cloutier 5b3de04fc1 Fix error from the last commit 2014-06-20 13:27:04 -04:00
Alexandre Cloutier eb3cc8916d The multiColumns view 2014-06-20 13:16:55 -04:00
Ludovic Marcotte 9fa0b42e19 Ignore SCHEDULE-AGENT for Thunderbird/Lightning 2014-06-20 11:25:02 -04:00
Ludovic Marcotte e048346cb7 Include, in our private NS, all ACLs defined on a calendar collectiob 2014-06-19 16:08:15 -04:00
Ludovic Marcotte 333b561a59 Applied patch from bug #2736 2014-06-16 15:30:26 -04:00
Ludovic Marcotte 50c0b49a6f Fix for bug #2813 2014-06-16 11:00:39 -04:00
Francis Lachapelle 8202d0588f Add documentation for SOGoSubscriptionFolderFormat
Fixes #2799
2014-06-16 10:20:34 -04:00
Francis Lachapelle d9b578b869 Wait 20 seconds before deleting temporary forms
Those temporary forms are created to download attachments.
Fixes #2811
2014-06-16 09:52:29 -04:00
Francis Lachapelle 5bb64916c6 Fix regression when attaching files to a reply 2014-06-12 09:09:08 -04:00
Ludovic Marcotte e7ddfb0546 Fix for bug #2805 2014-06-11 12:55:51 -04:00
Alexandre Cloutier 0e182f8436 Update SOGoAppointmentFolder.m
Fix the status filtering from 2 to 1
2014-06-11 11:25:17 -04:00
Alexandre Cloutier de2ee2322a Change the NSString with NSNumber and add some JavaScript 2014-06-11 10:24:04 -04:00
Ludovic Marcotte ce07695a55 Make sure to keep the / path prefix 2014-06-10 16:35:36 -04:00
Alexandre Cloutier 43ac57b671 display the number of active tasks in calendar view 2014-06-10 16:18:12 -04:00
Francis Lachapelle 7f7e3cb06a Fix folder name of new subscriptions
Fixes #2801
2014-06-10 14:48:25 -04:00
Francis Lachapelle 6b3a3f858b Update prototype.js to version 1.7.2 2014-06-10 14:32:35 -04:00
Ludovic Marcotte 0133bb3b6b Correctly update the cache on folder update/delete ops. 2014-06-10 13:07:14 -04:00
Ludovic Marcotte 91e3e19e40 Added the Ping ActiveSync command 2014-06-10 11:04:27 -04:00
Ludovic Marcotte 19a95a1818 Applied fix from #2809 2014-06-10 08:58:44 -04:00
Ludovic Marcotte 1292c191ec Make sure we don't have '-' in table names. 2014-06-10 08:46:35 -04:00
Ludovic Marcotte 77dad178d1 Make sure we don't have '-' in table names. 2014-06-10 08:45:35 -04:00
Ludovic Marcotte f48839bf55 Added (slightly modified) patch from #2806 2014-06-09 09:34:00 -04:00
Ludovic Marcotte 0f04be2bcb Added patch from #2808 2014-06-09 09:25:06 -04:00
Ludovic Marcotte 3f8bbe8c60 Applied patch from #2807 2014-06-09 09:14:30 -04:00
Francis Lachapelle 6b6ec8a2ae Update ChangeLog 2014-06-05 13:35:17 -04:00
Francis Lachapelle ad30df26af Preparation for release 2.2.5 2014-06-05 13:34:40 -04:00
Francis Lachapelle 6e56f46f86 Update Dutch, Finnish, German, Polish translations 2014-06-05 13:29:10 -04:00
Francis Lachapelle fe38518a36 Minor syntax and comments improvements 2014-06-05 12:14:34 -04:00
Francis Lachapelle e118a72eab Add meta tag to tell IE to use the highest mode 2014-06-05 10:32:13 -04:00
Ludovic Marcotte 72bec939d6 Fixed text/plain reencoding issues for Outlook 2014-06-04 15:56:22 -04:00
Ludovic Marcotte ba258ca806 Fixed repetitive events issues 2014-06-04 15:23:41 -04:00
Ludovic Marcotte 0c2e2f28f7 Don't try to add attachments during reply operations 2014-05-30 13:53:20 -04:00
Ludovic Marcotte f0dfe37a55 Avoid crashing when forwarding mails with no Subject header 2014-05-30 08:41:42 -04:00
Francis Lachapelle dace1439df Update ChangeLog 2014-05-29 11:16:59 -04:00
Francis Lachapelle d91b37413f Preparation for release 2.2.4 2014-05-29 11:16:40 -04:00
Francis Lachapelle bd916f06eb Update ChangeLog 2014-05-29 11:15:13 -04:00
Francis Lachapelle ecbe0858f7 Update translations 2014-05-29 11:14:23 -04:00
Francis Lachapelle 24095a464c Update CKEditor to version 4.4.1 2014-05-29 10:50:48 -04:00
Francis Lachapelle 9ce3b8ff8f Merge pull request #40 from dekkers/fix-unit-test
Fix unit test with gnustep 1.24
2014-05-29 10:32:30 -04:00
Jeroen Dekkers efc33d8174 Fix unit test by also checking for the different gnustep 1.24 ordering of elements 2014-05-29 15:53:13 +02:00
Jeroen Dekkers 93971dc434 Add $(TEST_TOOL) as dependency of make check 2014-05-29 15:35:46 +02:00
Francis Lachapelle fac9520f64 Fix update of participation status via CalDAV
Fixes #2786
2014-05-28 11:39:25 -04:00
Francis Lachapelle 9eb075cc3f Rename "Archive" to "Export" in Webmail
Fixes #2758
2014-05-28 11:24:10 -04:00
Francis Lachapelle c5922b07aa Restore options when editing a draft
Fixes #193
2014-05-28 11:21:11 -04:00
Ludovic Marcotte 51e07fc306 Fix over previous commit 2014-05-27 15:33:39 -04:00
Ludovic Marcotte d35c52bb38 Fix for bug #2688 2014-05-27 14:44:57 -04:00
Ludovic Marcotte 6bab4c94f2 Added an empty stub for the Provision command 2014-05-27 09:42:02 -04:00
Ludovic Marcotte c31429a5d5 Also include the BS character in non-safe ones. 2014-05-27 08:45:00 -04:00
Ludovic Marcotte 04bb88a470 Updated NEWS file regarding pull request #39 2014-05-26 13:25:39 -04:00
extrafu c79cd750d8 Merge pull request #39 from alexcloutier/fix/publicFolder_ConfigNaming
Added new SOGo configurable variable
2014-05-26 13:24:50 -04:00
Ludovic Marcotte 6fc81e61ec Fixed documentation: NGImap4ConnectionGroupPrefix -> NGImap4ConnectionGroupIdPrefix 2014-05-23 11:30:28 -04:00
Francis Lachapelle d9ad286650 Fix newline in signature of attachment
Fixes #2787
2014-05-23 11:23:02 -04:00
Alexandre Cloutier dd57d56cf9 remove crufts and applies comments 2014-05-23 10:15:21 -04:00
Ludovic Marcotte ab7780d617 Prevent a crash when someone tries to access /SOGo/Microsoft-Server-ActiveSync directly 2014-05-22 14:39:58 -04:00
Ludovic Marcotte cb9332f240 Updated NEWS file regarding #2775 2014-05-22 10:26:58 -04:00
Ludovic Marcotte 7b60ad4797 Added patch from #2775 2014-05-22 09:20:05 -04:00
Alexandre Cloutier 3261c21549 fix case where the displayed name for the subscribed folders is duplicated 2014-05-21 14:26:08 -04:00
Francis Lachapelle 364b409501 FIx mail templates for Brazilian Portuguese
Fixes #2738
2014-05-21 08:44:35 -04:00
Alexandre Cloutier 064565e1a9 Added new SOGo configurable variable for which you can change the default display when adding a shared calendar or a shared addressBook 2014-05-20 17:05:13 -04:00
Alexandre Cloutier f92d280fbb remove unneeded condition to fix navigation in print preview 2014-05-20 11:24:27 -04:00
Francis Lachapelle ea2bce706c Update NEWS file 2014-05-16 21:15:38 -04:00
Francis Lachapelle d74afaf295 Update French translation 2014-05-16 21:15:28 -04:00
Francis Lachapelle 5e7beb3345 Remove unused localizable strings 2014-05-16 21:14:59 -04:00
Francis Lachapelle 2df5887eec Merge pull request #36 from alexcloutier/feat/calendarPrint
New print option in Calendar module
2014-05-16 16:56:51 -04:00
Francis Lachapelle 3d1bdf1a09 Update French translation 2014-05-16 16:52:44 -04:00
Francis Lachapelle 5de1343506 Remove unused localizable string 2014-05-16 16:44:25 -04:00
Francis Lachapelle 1eaa3f3891 Update NEWS file 2014-05-16 16:34:17 -04:00
Francis Lachapelle c2d3a827bd Merge branch 'alexcloutier-feat/searchCapabilities' 2014-05-16 16:30:24 -04:00
Francis Lachapelle 6b72a8d126 Merge branch 'feat/searchCapabilities' 2014-05-16 16:28:43 -04:00
Francis Lachapelle 819d0641b7 Remove common localizable strings from UI/Contacts 2014-05-16 16:19:40 -04:00
Francis Lachapelle 5d7f4ba6c6 Restore localizable string
To avoid new translation ..
2014-05-16 15:59:52 -04:00
Francis Lachapelle 34a7e28858 Rename 'Properties' button of contacts to 'Edit' 2014-05-16 15:58:34 -04:00
Francis Lachapelle 87b010c700 Indentation 2014-05-16 15:57:33 -04:00
Francis Lachapelle a44b183b7e Merge pull request #38 from alexcloutier/fix/link_address
New AddressBook properties popup window
2014-05-16 15:33:23 -04:00
Alexandre Cloutier b488721f83 Reverse loop to make sure no objects is skipped 2014-05-16 15:00:47 -04:00
Alexandre Cloutier 8a03f3bd63 remove start date in tasks 2014-05-16 14:36:51 -04:00
Alexandre Cloutier f8c8abc989 Function isPublicAccessEnabled was missing 2014-05-16 13:50:52 -04:00
Alexandre Cloutier db8d9bb16c Repair broken logic 2014-05-16 11:29:37 -04:00
Alexandre Cloutier 2794425a3f added last changes from cgx 2014-05-16 10:04:37 -04:00
Ludovic Marcotte 2f7979c796 Fix for bug #2709 2014-05-16 08:33:06 -04:00
Ludovic Marcotte c426afd7f2 New cache subsystem for ActiveSync. 2014-05-15 15:03:24 -04:00
Alexandre Cloutier 07445eb069 Created a window for address book properties and add the cardDav URL 2014-05-15 14:45:53 -04:00
Ludovic Marcotte 93bf98c326 Fixed copyright 2014-05-15 14:45:32 -04:00
Ludovic Marcotte c08c3e27d5 Improved modseq code 2014-05-15 14:44:53 -04:00
Ludovic Marcotte c8860dc92b Dropped old user-settings for ActiveSync 2014-05-15 14:32:46 -04:00
Ludovic Marcotte 1a1543a380 Updated script to reflect new table names 2014-05-15 14:29:39 -04:00
Ludovic Marcotte d2d5467317 Removed unused fluff in the file. 2014-05-14 10:51:16 -04:00
Ludovic Marcotte 18443de9bf Updated copyright info 2014-05-14 09:58:05 -04:00
Ludovic Marcotte be72456a9a Renamed folder cache creation method 2014-05-14 09:56:10 -04:00
Ludovic Marcotte a54b3e4289 Renamed the default table name from socfs_ to sogo_cache_folder_ 2014-05-14 08:56:35 -04:00
Ludovic Marcotte 7a4feae8b8 Updated code to reflect cache regorg. 2014-05-14 06:56:05 -04:00
Ludovic Marcotte 99d49b9bd9 Updated code to use the category 2014-05-13 21:14:57 -04:00
Ludovic Marcotte 5f9fb4e1c4 Big refactor for new caching mechanism. 2014-05-13 21:06:59 -04:00
Ludovic Marcotte ef2188962a Renamed cache files for generalization.
The upcoming commit will rename the content.
2014-05-13 19:58:19 -04:00
Ludovic Marcotte 2922f15ca7 More rename 2014-05-13 18:03:37 -04:00
Ludovic Marcotte 41e6fb89d3 Renamed constants in preparation for the big cache cleanup 2014-05-13 17:54:02 -04:00
Ludovic Marcotte c4a3843695 Removed unused configuration parameters 2014-05-13 13:52:20 -04:00
Alexandre Cloutier bf67b6435f applies comments 2014-05-13 13:21:18 -04:00
Alexandre Cloutier b5319446db display and printing modification 2014-05-13 10:36:26 -04:00
Francis Lachapelle d58184af15 Fix synchronization of seen/unseen status of msgs 2014-05-13 10:15:02 -04:00
Francis Lachapelle fbc6856fd5 Improve contextual menu in events list 2014-05-12 16:06:49 -04:00
Francis Lachapelle 5c41915080 Fix focus of popup windows with FF on Windows 2014-05-12 15:25:50 -04:00
Francis Lachapelle 698524b39f Fix synchronization of seen/unseen status of msgs
Fixes #2715
2014-05-09 17:28:02 -04:00
Ludovic Marcotte 1f5a2a4c62 Fixed IMAP copy/move op between subfolder in different accounts 2014-05-09 15:40:57 -04:00
Alexandre Cloutier fc3cfa5484 applied comments 2014-05-08 19:14:39 -04:00
Alexandre Cloutier 593b44ed01 forgotten code 2014-05-08 17:53:20 -04:00
Alexandre Cloutier b2ed7e3f6b search capabilites 2014-05-08 17:17:05 -04:00
Ludovic Marcotte bc2b41f383 Fixed unit test. 2014-05-08 09:13:37 -04:00
Ludovic Marcotte 7d7961ffcf Fix for bug #2492 2014-05-02 13:35:21 -04:00
Francis Lachapelle 0b9afec635 Fix saving preferences with no Sieve requirements
Fixes #2746
2014-05-01 14:07:25 -04:00
Francis Lachapelle 4e42a6a689 Don't limit Sieve script to 8KB
Fixes #2745
2014-04-30 12:36:51 -04:00
Alexandre Cloutier da8febf138 Printing display appear on one page only, fix issues with browsers 2014-04-29 15:42:50 -04:00
Francis Lachapelle 8c563c2922 Fix possible exception when retrieving reminder
Fixes #2744
2014-04-29 14:26:18 -04:00
Alexandre Cloutier fa5cf55367 Update GNUmakefile 2014-04-28 15:42:17 -04:00
Alexandre Cloutier e43b704858 Update UIxCalViewPrint.js 2014-04-28 15:32:47 -04:00
Alexandre Cloutier 44a4baca7f fix the comments in the headers 2014-04-28 15:30:32 -04:00
Alexandre Cloutier 78447d81ae Code refactoring and retouch 2014-04-28 13:54:29 -04:00
Alexandre Cloutier 9dc07fccc0 It is now possible to print the calendar as a list, dayView or weekView 2014-04-25 18:04:24 -04:00
Ludovic Marcotte ba7b65cf7b Fix for bug #2733 2014-04-24 07:59:07 -04:00
Francis Lachapelle 66bfbeaac1 MailEditor: fix text conversion with HTML entities 2014-04-23 10:55:04 -04:00
Ludovic Marcotte 619cb2c0ec Fix for bug #2721 2014-04-23 09:22:20 -04:00
Alexandre Cloutier f9869d19b4 Finished the view, need to display the eventsblock 2014-04-22 17:47:29 -04:00
Alexandre Cloutier 57b747c24a Events list is done. 2014-04-17 17:33:30 -04:00
Alexandre Cloutier 8f6b0f80a7 Creation of the first version of the printing interface 2014-04-14 10:32:08 -04:00
Alexandre Cloutier cb5e6e7ef2 adding button print calendar toolbar, adding template for the print window, ajusting indentation 2014-04-14 10:32:08 -04:00
Jeroen Dekkers b5dc2e264d Link correctly against libraries used
Link the mapistore backend against libgnustep-base, libobjc,
libNGObjWeb. Link the SAML code against gobject-2.0.
2014-04-12 20:32:20 +02:00
Francis Lachapelle 49363cfe36 Update datepicker to latest version
From https://github.com/eternicode/bootstrap-datepicker/
2014-04-11 21:37:55 -04:00
Francis Lachapelle c345fc2b8d Fix display of category of events
Fixes #2703
2014-04-10 12:25:42 -04:00
Francis Lachapelle d200629b01 Fix CSS in contact editor and preferences module 2014-04-10 10:05:28 -04:00
Francis Lachapelle cfc1ac6b3b Add missing localizable string 2014-04-10 10:02:51 -04:00
Ludovic Marcotte e66ceaad07 Fixed gcc warnings and added some rationale around yesterday's fix 2014-04-10 09:40:25 -04:00
Ludovic Marcotte f370ac114a Now include message/rfc822 parts as attachments when forwarding mails 2014-04-10 09:24:43 -04:00
Ludovic Marcotte 75ee6b4806 Fixed once more true/false errors 2014-04-10 08:44:44 -04:00
Ludovic Marcotte 0961fbbab3 Properly escape attendee names in case they contain HTML entities 2014-04-10 06:59:18 -04:00
Ludovic Marcotte 0d1c39ca71 Added new configuration parameter to limit the window size 2014-04-09 20:12:19 -04:00
Ludovic Marcotte 5739356f88 Fix tests to handle list-component 2014-04-09 19:27:38 -04:00
Ludovic Marcotte 33467093c1 Fix for #2695 2014-04-09 18:03:33 -04:00
Ludovic Marcotte 96ece873ca Fix for bug #2654 2014-04-09 14:49:31 -04:00
Ludovic Marcotte 8909775cf6 Fix for #2680 2014-04-09 12:19:23 -04:00
Ludovic Marcotte 0ba59de88e Fixed formatting/warnings in previous commit. 2014-04-09 11:09:13 -04:00
extrafu 4fbe937f6d Merge pull request #22 from alexcloutier/fix/1046
BugFix #1046; Whenever the sieve server is unavailable an error message will appear
2014-04-09 11:01:19 -04:00
Ludovic Marcotte ab80e87a3f Applied patches from #2700 2014-04-09 10:57:56 -04:00
Alexandre Cloutier 068eb921aa rebase and fix comments made by extrafu 2014-04-09 10:48:47 -04:00
Alexandre Cloutier 5c13fade22 Fix merge 2014-04-09 10:35:10 -04:00
Ludovic Marcotte 371e5ead08 Updated the doc in prepration for the release 2014-04-09 10:34:48 -04:00
Alexandre Cloutier c5e6ccf332 Fix function sieveClient and the way the iVar Client is handled. Change behaviour of saveMailAccounts()so sogo wont crash if the user tries to resave his preferences after a connection error. 2014-04-09 10:31:34 -04:00
Alexandre Cloutier ec9d48c3a9 Change the function name getClient to sieveClient 2014-04-09 10:29:23 -04:00
Alexandre Cloutier 877082f042 Added missing functions getClient and IsSieveServerConnected and the changes that comes with it 2014-04-09 10:24:35 -04:00
Alexandre Cloutier 342b68fd44 Erase the merging conflicts writings 2014-04-09 10:23:43 -04:00
Alexandre Cloutier e24c22e3dc BugFix #1046; Whenever the sieve server is unavailable an error message will appear. 2014-04-09 10:23:43 -04:00
Ludovic Marcotte 7997448d41 Fixed issus in previous commits 2014-04-09 06:33:02 -04:00
Ludovic Marcotte 3629670fca Fix for #2489 2014-04-08 15:35:36 -04:00
Alexandre Cloutier c250b9a6d4 Fix deleting calendar
Added a "/" inside the function: deletePersonalCalendarConfirm().
2014-04-08 15:32:13 -04:00
extrafu afa564a6a6 Merge pull request #23 from alexcloutier/fix/1636
BugFix#1636; fix the issue where the user could add any birthday for his contact.
2014-04-08 13:17:54 -04:00
Alexandre Cloutier d9b99f536c Erased strings no longer used 2014-04-08 12:48:59 -04:00
Alexandre Cloutier 5699e5e1b4 Add datepicker for contact birthday 2014-04-08 12:12:30 -04:00
Francis Lachapelle e869406081 Minor CSS improvement in mail headers 2014-04-08 11:51:47 -04:00
Ludovic Marcotte 3e221253ad Fix for feature #1496 2014-04-08 11:19:53 -04:00
Alexandre Cloutier 446ef3467a Fix typo 2014-04-08 09:14:00 -04:00
extrafu bf64076b87 Merge pull request #29 from alexcloutier/feat/1496
New feature : 1496

Don't forget to fix the typo.
2014-04-07 19:42:31 -04:00
Alexandre Cloutier c9cbcf2566 applied Morgan's law 2014-04-07 16:40:44 -04:00
extrafu 4fe0358581 Merge pull request #20 from alexcloutier/fix/2616
bugFix #0002616 : change the behavior of ApplicationBaseURL.
2014-04-07 15:44:07 -04:00
Francis Lachapelle 534e4e3d4d Fix text nodes of message with HTML entitites 2014-04-07 11:21:52 -04:00
Alexandre Cloutier 09bcd2aee2 fix code 2014-04-07 10:59:38 -04:00
extrafu 526e21e837 Merge pull request #32 from dekkers/cleanup-generated-files
Delete generated source files when running "make clean".
2014-04-06 17:34:22 -04:00
Jeroen Dekkers c80e222210 Delete generated source files when running "make clean". 2014-04-06 22:44:50 +02:00
Francis Lachapelle 6e60bbb553 Fix saved HTML content of draft uploading a file 2014-04-04 20:20:32 -04:00
Ludovic Marcotte 846212336a Make use of a local pool to avoid over-memory usage 2014-04-04 16:53:58 -04:00
Alexandre Cloutier 349f4d824a Fix function sieveClient and the way the iVar Client is handled. Change behaviour of saveMailAccounts()so sogo wont crash if the user tries to resave his preferences after a connection error. 2014-04-04 15:04:37 -04:00
Alexandre Cloutier 2f565d2ec9 fix variable name for UIxFilterEditor.js
FolderEncoding to sieveFolderEncoding
2014-04-04 14:56:14 -04:00
extrafu eb7cabac71 Merge pull request #19 from alexcloutier/fix/2622
BugFix #0002622: The server Dovecot use by default an UTF-8 and by doing...
2014-04-04 09:21:49 -04:00
Ludovic Marcotte 2ff4498983 Fixed previous commit 2014-04-04 08:44:50 -04:00
Ludovic Marcotte 3eec753b73 Slightly improved previous pull request merge. 2014-04-04 08:39:13 -04:00
extrafu 7b0ffacff0 Merge pull request #24 from alexcloutier/fix/2612
It is now possible to see the version on the general page of the preferences window
2014-04-04 08:33:39 -04:00
Alexandre Cloutier f999c87d4d added traduction in localstring french, added some specification in function sogoVersion 2014-04-03 17:09:00 -04:00
Francis Lachapelle 378f2b5876 Preparation for release 2.2.3 2014-04-03 10:05:43 -04:00
Francis Lachapelle d091b3d7cd Update ChangeLog 2014-04-03 10:01:40 -04:00
Francis Lachapelle 370e1e6d26 Update CKEditor to version 4.3.4 2014-04-03 10:01:01 -04:00
Francis Lachapelle e2b3d5a7ff Update translations 2014-04-03 09:54:27 -04:00
Ludovic Marcotte 078b88a396 Fix for #2686 2014-04-02 18:14:17 -04:00
Francis Lachapelle ee09b80fc3 Simplify [UIxContactEditor addressBookDisplayName]
We were trying to translate the default address book name to the user's
language, but the method [SOGoContactFolders defaultFolderName] is
already returning a translated string, making the whole logic useless.
2014-04-02 10:15:59 -04:00
Francis Lachapelle 99d9615c92 Update NEWS file 2014-04-02 10:09:09 -04:00
Francis Lachapelle 79c3fa8ad2 Merge pull request #30 from dekkers/remove-executable-permission-from-jquery
Remove executable permission from jQuery modules
2014-04-01 11:42:07 -04:00
Francis Lachapelle fd07112113 Merge pull request #31 from opensaucesystems/patch-1
Fix email validation regexp to allow gTLDs
2014-04-01 08:18:51 -04:00
opensaucesystems ce5d591d1d Fix email validation regexp to allow gTLDs
New generic TLDs can be as long as 13 characters.
2014-04-01 12:35:18 +01:00
Jeroen Dekkers e603742d71 Remove executable permission from jQuery 2014-03-29 17:11:05 +01:00
Ludovic Marcotte 585d224a15 Fixed the AS bundle common makefile 2014-03-28 16:44:33 -04:00
Ludovic Marcotte 6a39b48a37 Fix for bug #2691 2014-03-28 15:22:45 -04:00
Ludovic Marcotte 633723a470 Fix for bug #2681 2014-03-28 14:44:00 -04:00
Ludovic Marcotte ba32b95308 Fixed the ActiveSync issue marking mails as read when downloading them 2014-03-28 14:18:48 -04:00
Alexandre Cloutier 03d5975be3 Changed strings in french and change the instanciation of dictionary(addressBooksIDWithDisplayName) to release it manually 2014-03-28 10:28:33 -04:00
Alexandre Cloutier 1da1764aae The collected address book will be created only if the user select it in the preferences. Fix labels. 2014-03-27 15:27:48 -04:00
Francis Lachapelle 6e4f776d4b Fix detection of IMAP flags support in JavaScript
Fixes #2664
2014-03-27 12:06:24 -04:00
Alexandre Cloutier 365e271a84 Correct typo 2014-03-25 15:44:28 -04:00
Alexandre Cloutier bce701208a Added the modifications specified by extrafu 2014-03-25 14:53:42 -04:00
Alexandre Cloutier b16911edc1 Modified the displayed name of SOGo version and added the label in the .lproj 2014-03-24 13:55:52 -04:00
Alexandre Cloutier 76307cfaaf New feature : 1496; Unknown outgoing email addresses can now be automatically be added to your address books. 2014-03-24 13:41:57 -04:00
Francis Lachapelle e5fb7dc7b8 Fix JavaScript exception in Contacts module
Fixed calling unescapeHTML on null variables. Also fixed errors on IE7
(and possibly other versions).
2014-03-24 12:43:34 -04:00
Francis Lachapelle 50e7ea7188 Fix possible exception when retrieving reminder
Fixes #2678
2014-03-24 07:42:57 -04:00
Ludovic Marcotte 89e61f6d5d Fixed SOPE include path 2014-03-21 15:37:14 -04:00
Francis Lachapelle 85f4af56e9 Update ChangeLog 2014-03-21 15:22:28 -04:00
Francis Lachapelle 04bdb22b00 Preparation for release 2.2.2 2014-03-21 15:20:45 -04:00
Ludovic Marcotte 874b1d9eba Added NEWS entry for previous commit 2014-03-21 14:08:53 -04:00
Ludovic Marcotte b143688419 Fix for bug #2669 2014-03-21 13:55:59 -04:00
Francis Lachapelle 5f3d2d988e Update translations 2014-03-21 13:51:36 -04:00
Francis Lachapelle 93f1540c17 Update jQuery File Upload to version 9.5.7 2014-03-21 13:47:40 -04:00
Francis Lachapelle 877e44c6d2 Update CKEditor to version 4.3.3 2014-03-21 13:32:28 -04:00
Ludovic Marcotte 4ca3d351e0 Fixed previous commit 2014-03-21 09:05:52 -04:00
Ludovic Marcotte 19b6704955 Only touch text/plain and text/html parts during Outlook sanitization 2014-03-21 09:02:39 -04:00
Francis Lachapelle 64787555ff Fix classification icon of events
Fixes #2664
2014-03-20 22:14:45 -04:00
Francis Lachapelle 27ffcf240f Fix handling of accents when filtering contacts
Fixes #2656
2014-03-20 15:29:32 -04:00
Francis Lachapelle 893d75bd5f Update Transifex configuration
Added new SoObjects/Mailer resource.
2014-03-20 14:18:03 -04:00
Ludovic Marcotte b0f26f1dcc Updated the doc regarding the isAddressBook parameter in sources. 2014-03-20 09:57:19 -04:00
Ludovic Marcotte a196ed210e Removed old values. 2014-03-19 17:04:04 -04:00
Ludovic Marcotte 1c28a4b4d2 Fixed translations for "OtherUsersFolderName" and "SharedFoldersName" (#2657) 2014-03-19 17:02:10 -04:00
Ludovic Marcotte fc56493b78 Added sanitization support for Outlook/ActiveSync 2014-03-19 11:44:36 -04:00
Ludovic Marcotte 3a33010918 Updated NEWS file regarding previous commit 2014-03-19 11:33:00 -04:00
Ludovic Marcotte 83bccda551 Avoid creating duplicates in Outlook on MoveItems (#2650) 2014-03-19 11:31:54 -04:00
Ludovic Marcotte 35d71f6150 Added deviceType capabilities to the code 2014-03-19 11:30:18 -04:00
Ludovic Marcotte e92a145325 Updated NEWS file regarding previous commit 2014-03-19 08:27:36 -04:00
Ludovic Marcotte c3062284e3 Disabled provisionning for now, as we don't support it. 2014-03-18 19:06:41 -04:00
Skruppy 1c3f1af662 ModulesConstraints tests all values of a multi-valued attributes 2014-03-15 15:10:26 +01:00
Francis Lachapelle e2f192b793 Fix display of company/department of cards
Fixes #2662
2014-03-14 15:45:12 -04:00
Francis Lachapelle b8f239bf34 Fix construction of mail folders tree 2014-03-14 15:34:43 -04:00
Francis Lachapelle e968be8024 Bump version to 2.2.2 2014-03-14 13:02:27 -04:00
Francis Lachapelle 3c3bebeee3 Fix resource conflict check when creating event
Fixes #2541
2014-03-14 09:23:55 -04:00
Francis Lachapelle 26e9defdbd Update French translation 2014-03-14 09:17:52 -04:00
Francis Lachapelle 8742f28c29 Fix decoding of HTML entitities in reminder alert
Fixes #2659
2014-03-13 08:44:47 -04:00
Francis Lachapelle bd577fd513 Fix unseen count of folders beginning with a digit
Fixes #2652
2014-03-13 08:41:42 -04:00
Francis Lachapelle c8550c8a4a Fix copy/move to folder with numerical prefix
Fixes #2658
2014-03-12 16:35:22 -04:00
Ludovic Marcotte 1bdf88fb67 Don't try to delete an already non-existant object (#2653) 2014-03-11 13:21:05 -04:00
Alexandre Cloutier d108777e89 Display the version at the top of the general tap 2014-03-11 10:25:01 -04:00
Francis Lachapelle 167a06e3e9 Merge pull request #25 from dani/master
Disable file paste support in mail editor
Fixes #2641
2014-03-11 10:16:52 -04:00
Daniel B. af68f10115 Fix #2641
Disabling the pasteZone support (which only works in Chrome or Opera anyway) fixes the problem of unwanted PNG attachment when you paste the recipient list from Excel
2014-03-11 09:23:13 +01:00
Francis Lachapelle cbd22762c3 Fix possible exception when retrieving reminder
Fixes #2647
Fixes #2648
2014-03-10 14:47:01 -04:00
Alexandre Cloutier 8cc352fb28 It is now possible to see the version on the general page of the preferences window 2014-03-10 14:45:10 -04:00
Alexandre Cloutier 0d69a476bc add specific date for limiting the user to today's for his contact birthday 2014-03-10 12:16:12 -04:00
Alexandre Cloutier cee1e529f8 BugFix#1636; fix the issue where the user could add anything for the birthday of his contacts 2014-03-10 12:05:01 -04:00
Alexandre Cloutier 3a681bd5a5 Change the function name getClient to sieveClient 2014-03-10 10:53:44 -04:00
Alexandre Cloutier f5faa60814 Added missing functions getClient and IsSieveServerConnected and the changes that comes with it 2014-03-10 10:33:27 -04:00
Alexandre Cloutier f8939bfb3e Change the variable name for sieveFolderEncoding instead of folderEncoding 2014-03-10 10:07:47 -04:00
Ludovic Marcotte 78636f0396 Added default value for WOListenQueueSize 2014-03-09 15:58:11 -04:00
Ludovic Marcotte 037c2d3ddf Added documentation for WOListenQueueSize 2014-03-09 15:56:38 -04:00
Francis Lachapelle 41fe9195f2 Update ChangeLog 2014-03-07 14:00:51 -05:00
Francis Lachapelle 23789b48bc Update Dutch translation 2014-03-07 14:00:08 -05:00
Francis Lachapelle 142296f71e Preparation for release 2.2.1 2014-03-07 10:53:17 -05:00
Francis Lachapelle 3bae2387d4 Fix contact autocompletion when UID is a digit 2014-03-06 22:13:17 -05:00
Francis Lachapelle 6cecca6c4f Fix CSS id for string prefixed with a digit
When encoding a string as a CSS identifier, we must add an underscore if
the strings starts with a digit.
2014-03-06 21:32:36 -05:00
Francis Lachapelle 28b1938bd9 Show folder name in dialog when renaming folder 2014-03-06 21:25:48 -05:00
Alexandre Cloutier f4d189ffc8 Erase the merging conflicts writings 2014-03-06 15:20:41 -05:00
Alexandre Cloutier 1b9ac03e94 BugFix #1046; Whenever the sieve server is unavailable an error message will appear. 2014-03-06 14:57:53 -05:00
Alexandre Cloutier 6ad87052ba bugFix #0002616 : change the behavior of ApplicationBaseURL. Now the object return a standard path(without a slash at the end of the path) That means every string added the URL ApplicationBaseURL must start with a Slash. 2014-03-06 14:47:54 -05:00
Alexandre Cloutier e7a16cba0d BugFix #0002622: The server Dovecot use by default an UTF-8 and by doing so it cause a wrong re-encoding in UTF-7 when reaching the sieve server (knowing that the foldername in sieve are encoded in UTF-7). Since it is not the case with a Cyrus server, I created a new variable available in the sogo.conf that let you specified the type of encoding you need. By default the encoding is set to UTF-7. ex : SOGoFolderEncoding = 'UTF-7' 2014-03-06 14:33:31 -05:00
Ludovic Marcotte 31ace947cb Fixed race condition when syncing huge amount of deleted messages using AS 2014-03-06 14:16:08 -05:00
Ludovic Marcotte 0cea36df2e Updated NEWS regarding previous commit 2014-03-06 14:10:47 -05:00
Ludovic Marcotte afd7452323 Fixed returned date format and fixing missing 'name part' in address 2014-03-06 14:05:59 -05:00
Francis Lachapelle e4a21bcef5 Webmail: fix encoding of subfolder name
Fixes #2637
2014-03-06 09:50:53 -05:00
Francis Lachapelle 0c99323db3 Fix possible exception when retrieving reminder
Fixes #2624
2014-03-05 13:42:38 -05:00
Ludovic Marcotte da208d5b4a Updated NEWS regarding previous commit 2014-03-05 09:09:33 -05:00
Ludovic Marcotte 158af71152 Fix for bug #2609 2014-03-05 09:07:39 -05:00
Francis Lachapelle 163bce39b5 Fix list sorting of events by calendar name
Fixes #2629
2014-03-04 22:03:28 -05:00
Francis Lachapelle 02c72fee6a Fix unsubscription when renaming an IMAP folder
Fixes #2630
2014-03-04 21:32:57 -05:00
Francis Lachapelle 8bef84bded Update translations 2014-03-04 09:23:17 -05:00
Francis Lachapelle 8db3b22eb9 Bump version to 2.2.0a 2014-03-03 22:08:29 -05:00
Francis Lachapelle 1aabcf04b5 Fix sogo-tool operations on Sieve script
Fixes #2617
2014-03-03 22:07:24 -05:00
Francis Lachapelle c6b227160c Update ChangeLog 2014-02-24 16:53:46 -05:00
Francis Lachapelle 5f2920db9b Update translations 2014-02-24 16:49:16 -05:00
Francis Lachapelle 761a7e2be1 Update Microsoft Outlook Configuration guide 2014-02-24 16:42:59 -05:00
Francis Lachapelle 9ed1d57ec2 Fix auto-acceptation of resources as attendees
Fixes #2541
2014-02-24 16:07:55 -05:00
Francis Lachapelle 2b6428efd0 Always check resource conflict for new events
Fixes #2541
2014-02-24 07:57:11 -05:00
Francis Lachapelle be36e0ceea Fix view changes in calendar module
Fixes #2613
2014-02-21 20:37:44 -05:00
Francis Lachapelle 070d3dd825 Extract node value with 'textValue' 2014-02-21 15:48:41 -05:00
Francis Lachapelle 96f2552b45 Preparation for release 2.2.0 2014-02-19 21:57:01 -05:00
Francis Lachapelle 2948920e0b Improve display of contact
Fixes #2350
2014-02-18 16:15:06 -05:00
Francis Lachapelle 212d7149ed Fix display of a contact's birthday
Fixes #2503
2014-02-18 10:13:34 -05:00
Ludovic Marcotte 668c7e8b49 Correctly handle email invitations as attendee/organizer 2014-02-17 16:08:29 -05:00
Ludovic Marcotte 9851c32a1e Fixed the handling of organizers 2014-02-17 15:49:22 -05:00
Francis Lachapelle e7f27427c8 Add missing import in UIxPreferences.m 2014-02-17 15:42:55 -05:00
Francis Lachapelle f0a29d3ca2 Fix debian dependencies for sogo-activesync 2014-02-17 15:05:31 -05:00
Ludovic Marcotte ec0a5ac4bf Properly handle event updates/pull when we are or not an attendee/organizer 2014-02-17 11:30:41 -05:00
Ludovic Marcotte 4ca8b9d0aa Copyright updates 2014-02-17 11:30:00 -05:00
Ludovic Marcotte d560d0e470 Always return a response avoiding iOS crashes on no-changes 2014-02-17 11:28:06 -05:00
Francis Lachapelle 401320e08b Contact: fix display of urls 2014-02-17 11:12:09 -05:00
Ludovic Marcotte 8083b41092 Added the context everywhere 2014-02-17 10:01:44 -05:00
Ludovic Marcotte 9218c7f253 Added missing recurrences support, improved MeetingResponse, added WindowSize support.
Also more bug fixes regarding event invitations, and ServerId handling for
calendar objects.
2014-02-17 08:46:05 -05:00
Ludovic Marcotte 4d1fdb33f5 Deleted wrongly added file 2014-02-17 08:42:35 -05:00
Ludovic Marcotte 2356562778 Added method to get synctag starting from an other one.
We also no longer fetch vanished items of modseq == 0
2014-02-17 08:41:12 -05:00
Ludovic Marcotte c686e3294d Added method to sanitize calendar "ServerId" 2014-02-17 08:39:48 -05:00
Ludovic Marcotte 1ff91f7b59 Added -activeSyncRepresentation to NSData objects 2014-02-17 08:38:34 -05:00
Francis Lachapelle b34c6324cd Fix custom mail labels in Sieve filter editor 2014-02-14 21:32:33 -05:00
Ludovic Marcotte 75c8362df8 Avoid over-using LDAP connections when decomposing groups 2014-02-14 16:39:26 -05:00
Ludovic Marcotte ae07de5f6f Updated the Active Sync documentation 2014-02-14 13:46:21 -05:00
Francis Lachapelle 06d2364ea2 Improve display of toolboor menus with checkmarks 2014-02-13 12:56:24 -05:00
Francis Lachapelle 29e081ec56 Add more parameters examples to sogo.conf 2014-02-13 12:53:07 -05:00
Francis Lachapelle 113b02fd71 Fix encoding of contact ID in Ajax requests 2014-02-13 12:12:31 -05:00
Francis Lachapelle 35b108e645 Contact: fix display of links 2014-02-13 12:11:25 -05:00
Ludovic Marcotte 70266155d3 Fix double return 2014-02-12 21:55:09 -05:00
Francis Lachapelle fcfd8be771 Improve URL handling in popup of events 2014-02-10 22:05:35 -05:00
Francis Lachapelle b91032db8e Cleanup common English Localizable.strings 2014-02-10 22:05:35 -05:00
Ludovic Marcotte f4874600fe Bumped to v14.1 2014-02-10 20:17:54 -05:00
Ludovic Marcotte b14e99b32a New prefs for intervals, fixed missing events in meeting requests, bumped v14.1 2014-02-10 20:16:43 -05:00
Francis Lachapelle ea4b21e991 Decode HTML entities in JSON of calendar module 2014-02-10 13:49:02 -05:00
Francis Lachapelle 0307b8339a Detect URLs in popup of events 2014-02-10 13:45:51 -05:00
Francis Lachapelle b5f1d3a19a Guide: add SOGoCalendarDefaultReminder paramter 2014-02-10 11:25:38 -05:00
Ludovic Marcotte 8225f76279 Fixed globalobjid so it doesn't contain \n characters! 2014-02-07 16:17:11 -05:00
Francis Lachapelle c94595ea7f Escape HTML in CSS dialogs 2014-02-07 16:12:14 -05:00
Francis Lachapelle 3a5e44e7eb Decode HTML entities in JSON of calendar module 2014-02-07 15:53:39 -05:00
Francis Lachapelle 80a0940765 Escape HTML in JSON of contacts module 2014-02-07 15:52:43 -05:00
Francis Lachapelle 7118bbe0ab Replace '/' by '-' in filenames of attachments
Fixes #2537
2014-02-07 14:00:36 -05:00
Francis Lachapelle eee5beb698 Add message-id header to appointment notification
Fixes #2535
2014-02-07 10:52:06 -05:00
Ludovic Marcotte 3363b253ac Set additional properties on meeting requests 2014-02-07 10:45:09 -05:00
Francis Lachapelle 4070b9222d Rework HTML of appointment notifications
Needed to simplify the HTML so it displays properly in Outlook.

Fixes #2233
2014-02-07 09:59:45 -05:00
Francis Lachapelle 5ea56a6f8a Enlarge the note field of the contact editor 2014-02-06 21:55:28 -05:00
Ludovic Marcotte 379258de59 Pimped the doc for AS support and dropped all references to Funambol. 2014-02-06 21:25:08 -05:00
Ludovic Marcotte 93b3685aa4 Added birthday support 2014-02-06 19:35:23 -05:00
Ludovic Marcotte c4dc4d4eda Fixed compilation warning 2014-02-06 17:59:33 -05:00
Ludovic Marcotte c6d104fac5 Fixed contact sync'ing on Android 2014-02-06 17:57:01 -05:00
Francis Lachapelle ef79c09642 Don't use the HTML editor with Internet Explorer 7 2014-02-06 14:43:05 -05:00
Francis Lachapelle aeb712083a Fix static array retain 2014-02-06 14:37:43 -05:00
Francis Lachapelle 2c678101fc Fix handling of ACLs with multiple groups
Fixes #1854
2014-02-06 14:23:09 -05:00
Ludovic Marcotte b95362f963 Now make use of a NGMimeFileData object to avoid broken SOPE behaviour 2014-02-06 14:05:00 -05:00
Ludovic Marcotte 3175a9169f Mapped lots of contact properties 2014-02-05 20:56:01 -05:00
Ludovic Marcotte 9311f05cc0 Fixed the non-filtering of recurrence exceptions 2014-02-05 17:30:34 -05:00
Francis Lachapelle 78cbcfb560 Update translations 2014-02-05 16:15:30 -05:00
Ludovic Marcotte b8610b3eca Extended GetItemEstimate to GCS collections 2014-02-05 16:12:08 -05:00
Francis Lachapelle 1a7fc2a0e9 Escape HTML in JSON of calendar module
Fixes #2598
2014-02-05 16:06:20 -05:00
Ludovic Marcotte f7a20d0a83 Fixed broken encoding of single-value element 2014-02-05 15:23:09 -05:00
Francis Lachapelle a1cf066828 Update translations 2014-02-05 11:43:25 -05:00
Francis Lachapelle 359b6a99aa Encode HTML entities for inline forwards in text
Fixes #2411
2014-02-05 11:17:22 -05:00
Francis Lachapelle 826537ed01 Fix caching of DN in LDAP source 2014-02-05 09:04:00 -05:00
Ludovic Marcotte 3950e9d4c3 Moved DN cache to SOGoCache 2014-02-04 21:03:11 -05:00
Francis Lachapelle 9885211a5b Replace VARCHAR(1000000) by TEXT field type
Fixes #2516
2014-02-04 17:55:49 -05:00
Francis Lachapelle ef1be5dc5f Improve deleting occurences of recurrent events 2014-02-04 17:55:49 -05:00
Ludovic Marcotte 4e42d5d410 Disabled debugging... 2014-02-04 15:07:23 -05:00
Ludovic Marcotte 31969d162d Properly escape some control chars (and generalized it) 2014-02-04 15:03:02 -05:00
Ludovic Marcotte 2ff3b5ef5f First pass at 'push' support for Ping and Sync 2014-02-04 11:19:33 -05:00
Ludovic Marcotte 7fe48a1555 Fix for bug #2544 2014-02-04 09:02:40 -05:00
Francis Lachapelle fcddeb4224 Visually identify users with no freebusy
Fixes #2565
2014-02-03 15:15:14 -05:00
Francis Lachapelle f1cb87aa02 Convert JS alerts to CSS dialogs in aptmt editor 2014-02-03 12:03:51 -05:00
Francis Lachapelle a6424680cc Respect max bookings of resources in freebusy data
Fixes #2560
2014-02-03 11:56:00 -05:00
Francis Lachapelle b3dc645282 Warn user when dnd failed with resource conflict
Fixes #1613
2014-02-03 11:09:03 -05:00
Francis Lachapelle 2f0419c18a Warn user when overbooking a resource
Fixes #2541
2014-02-03 11:03:23 -05:00
Ludovic Marcotte 9e9407cf30 First pass at event invitations support + few bug fixes. 2014-02-03 10:24:33 -05:00
Ludovic Marcotte d709a1216b Updated NEWS file 2014-02-03 09:54:21 -05:00
Ludovic Marcotte 588352be7d Fix for bug #2587 2014-02-03 09:53:47 -05:00
Ludovic Marcotte a40d7ca342 Updated NEWS file 2014-01-31 15:11:13 -05:00
Ludovic Marcotte e4ce687e29 Update the content when the request is from Active Sync 2014-01-31 15:05:33 -05:00
Ludovic Marcotte bcb0764b19 Fix for bug #2505 2014-01-31 15:04:49 -05:00
Ludovic Marcotte ddd7be4333 Fix for bug #2187 2014-01-31 15:03:40 -05:00
Ludovic Marcotte d9f4a9935a Properly escape all foldernames 2014-01-31 10:33:36 -05:00
Francis Lachapelle ae75fee512 Update NEWS file 2014-01-30 10:37:36 -05:00
Ludovic Marcotte 8cdacd065f Properly escape the filename 2014-01-30 08:25:55 -05:00
Ludovic Marcotte af6a69c9fc Expunge immediately after MoveItems to force the Delete response 2014-01-29 11:21:36 -05:00
Ludovic Marcotte dc41e29f05 Fixed the MoveItems response 2014-01-29 11:16:58 -05:00
Ludovic Marcotte afc7519beb Properly escape values 2014-01-29 10:30:31 -05:00
Ludovic Marcotte f2d5a76911 Type fix for recurrence rules. 2014-01-29 09:48:18 -05:00
Francis Lachapelle 342ad84a24 Fix issues with contextual menu in calendars
Creating an event or a task using the contextual menu will now consider
the day and hour of the menu position (fixes #2557).
The next/previous day/month menu options have been fixed.
The menu will now disappear when clicking outside the contextual menu on
the calendar area.
2014-01-28 15:42:02 -05:00
Ludovic Marcotte 9580a8f8ee Added initial support for recurring events. 2014-01-28 14:26:35 -05:00
Ludovic Marcotte a96380a0dc Fixed SyncKey issue not being updated during the sync operation 2014-01-28 13:51:21 -05:00
Ludovic Marcotte 2fed02da59 When creating a new object, mark it as new. 2014-01-28 13:21:34 -05:00
Francis Lachapelle 84dc08adb6 Fix display of folder names in filter editor
Fixes #2569
2014-01-27 15:43:48 -05:00
Francis Lachapelle c160edf20a Add support for Sieve body extension 2014-01-27 15:09:22 -05:00
Ludovic Marcotte 3b7a3c94d4 Properly escape fields and improved data dumps. 2014-01-27 11:30:43 -05:00
Ludovic Marcotte 7b97e28cff Fixed compiler warning 2014-01-24 16:33:31 -05:00
Ludovic Marcotte 81bf1b41e9 Fixed the rename operation to force a FolderSync 2014-01-24 16:28:08 -05:00
Ludovic Marcotte ea86f136b7 Properly escape folder/file names and fixed date representation in emails 2014-01-24 14:10:19 -05:00
Francis Lachapelle fc0c580fe1 Fix validation of subscribed folders
Fixes #2583
2014-01-24 13:48:01 -05:00
Ludovic Marcotte 42a7bcb9ac Added verbosity in case wbxml <-> xml conversions fail 2014-01-24 11:44:12 -05:00
Ludovic Marcotte 9669f2bbba Added more props and fixed the NativeBodyType preventing OL2013 to work 2014-01-24 11:09:37 -05:00
Ludovic Marcotte 2563408872 Improved the README regarding MS licensing 2014-01-24 07:38:03 -05:00
Ludovic Marcotte dbea244f49 Merge branch 'master' of https://github.com/inverse-inc/sogo 2014-01-24 07:37:52 -05:00
Francis Lachapelle 0f9d8cdd2c Remove xml tag before doctype declaration 2014-01-23 14:48:36 -05:00
Francis Lachapelle 5105dbb342 Make all attachments available when re/fwd'ing
To do so, we save the draft to the mailstore.
2014-01-23 14:39:03 -05:00
Francis Lachapelle b26e767a10 Respect signature placement when forwarding a msg 2014-01-23 14:34:44 -05:00
Francis Lachapelle 940f85fde2 Add missing localizable string to webmail 2014-01-23 11:25:14 -05:00
Ludovic Marcotte adee80529e Added more event props and fixed date issues 2014-01-23 11:09:32 -05:00
Francis Lachapelle 295dfcfdd5 Webmail: allow the backspace on any platform 2014-01-23 10:21:22 -05:00
Ludovic Marcotte aa18abd842 Added more props and cleaned up the code 2014-01-23 09:41:41 -05:00
Francis Lachapelle feb398d59c Fix IE11 issue with mail editor 2014-01-23 09:15:34 -05:00
Francis Lachapelle 19b404de45 Update French translation 2014-01-23 08:17:16 -05:00
Jean Raby d1a384e539 Send IMIP responses if the event is in the future
Avoids sending responses for past events when importing events into
a new calendar from thunderbird or any DAV client.
2014-01-22 11:40:04 -05:00
Ludovic Marcotte e7f38f940e Moved the cards' logic into a category and added support for more AS ones 2014-01-22 11:27:27 -05:00
Ludovic Marcotte f7ba5d2346 Don't add DateCompleted if none exist 2014-01-22 11:25:18 -05:00
Ludovic Marcotte eeddf43a78 Add the milliseconds 2014-01-22 11:22:52 -05:00
Ludovic Marcotte eabe829236 Don't add empty <Commands> and specify the folder Class 2014-01-22 11:02:12 -05:00
Ludovic Marcotte 762b841249 Avoid crashes on broken configurations 2014-01-21 16:40:57 -05:00
Francis Lachapelle 3090448fcb Update prototype.js to fix IE 10 issues
Updated to commit @8c9ead49ec of
https://github.com/sstephenson/prototype/
2014-01-20 15:43:33 -05:00
Ludovic Marcotte a3e1d4813a Removed debug + refactored NSDate class 2014-01-20 10:21:33 -05:00
Ludovic Marcotte 046a645119 Refactored the code and added support for FilterType 2014-01-20 10:13:16 -05:00
Ludovic Marcotte 07d4b2bae2 Merge branch 'master' of https://github.com/inverse-inc/sogo 2014-01-16 15:13:29 -05:00
Ludovic Marcotte 343f2d8bfe Fixed the GetChanges detection and added FilterType decoding 2014-01-16 15:13:09 -05:00
Jean Raby 65276f7dc0 Add dependency on tmpwatch. The cronjob uses it.
Fixes #2577
2014-01-15 16:37:24 -05:00
Jean Raby 24663682d6 New package: sogo-activesync + sogo-tool fixes
Added dependency on sogo = %version for sogo-tool
2014-01-15 12:08:29 -05:00
Jean Raby 57cd315f2a explicitly list all *.SOGo folders
Otherwise, ActiveSync.SOGo would be listed twice, once in sogo-activesync and
once in sogo.
2014-01-15 11:07:14 -05:00
Ludovic Marcotte 29fcfda118 Implemented FolderDelete for mail folders 2014-01-15 09:36:25 -05:00
Ludovic Marcotte ada90677e1 Correctly update the SyncKey when creating or updating folders 2014-01-14 16:08:04 -05:00
Ludovic Marcotte 4c9c07e358 Merge branch 'master' of https://github.com/inverse-inc/sogo 2014-01-14 15:47:52 -05:00
Ludovic Marcotte b71180b006 Use the right DeviceId 2014-01-14 15:47:33 -05:00
Jean Raby 1ed41e2831 New deb package: sogo-activesync 2014-01-14 14:39:51 -05:00
Ludovic Marcotte 948553dce3 Properly extract the foldername 2014-01-14 13:50:17 -05:00
Jean Raby 74adf78446 Fix include directories for libwbxml 2014-01-14 13:37:51 -05:00
Ludovic Marcotte ee0ae8a1c0 Correctly add the folder type prefix when creating them 2014-01-14 11:44:33 -05:00
Ludovic Marcotte 38c649751c If GetChanges is omitted, consider it as YES 2014-01-14 11:41:26 -05:00
Ludovic Marcotte 645c718dfa Fixed broken comparison and added stub for processMeeting... 2014-01-14 10:49:55 -05:00
Ludovic Marcotte 02992a7018 Correctly decode base64 text parts before returning them 2014-01-14 10:42:15 -05:00
Ludovic Marcotte 0ffa0649c5 Wrap Fetch responses into <Responses> tags so iOS works correctly 2014-01-14 10:09:10 -05:00
Ludovic Marcotte 7c7cabe432 First pass at organizer/attendees support 2014-01-13 16:25:14 -05:00
Ludovic Marcotte bb9c4cf039 Handle not found objects and correctly get all "Collection" 2014-01-13 16:24:15 -05:00
Ludovic Marcotte c252f5b7a8 Fixed the license indent 2014-01-13 11:46:32 -05:00
Ludovic Marcotte 2e44ac0f9b Fixed MoveItems and also fixed Ping with no content 2014-01-13 10:19:00 -05:00
Ludovic Marcotte 2a9ccf8122 Now able to grab the command from the URI 2014-01-13 10:18:20 -05:00
Ludovic Marcotte f74066c9a6 Support for more props 2014-01-11 19:31:39 -05:00
Ludovic Marcotte ee49836f2e Disabled debugging... 2014-01-10 16:49:40 -05:00
Ludovic Marcotte bf798061d3 Fixed timezones support for events and added more supported props 2014-01-10 16:48:39 -05:00
Ludovic Marcotte 834e05bab1 Fixed typo messing up adds 2014-01-10 15:29:57 -05:00
Ludovic Marcotte e8438a6235 Don't write decoded stuff if not needed 2014-01-10 14:53:49 -05:00
Ludovic Marcotte 68dafdfdeb Removed old comments 2014-01-10 14:25:00 -05:00
Ludovic Marcotte e5bc46710c Initial Active Sync Support! 2014-01-10 14:12:53 -05:00
Ludovic Marcotte 7355eae1dc Now able to set Active Sync metadata in the user settings 2014-01-10 14:10:53 -05:00
Ludovic Marcotte 1d9febb511 Correctly handle the Active Sync requests 2014-01-10 14:10:16 -05:00
Ludovic Marcotte e21b30d768 Code cleanups 2014-01-10 14:09:32 -05:00
Ludovic Marcotte ae200360ba Code cleanups 2014-01-10 14:09:02 -05:00
Ludovic Marcotte e217ffb6c4 Code generalization to be usable from the ActiveSync bundle 2014-01-10 14:08:12 -05:00
Ludovic Marcotte a4a3a735b4 Moved the folder metadata generation to SoObject and added 'tag based' sync'ing support for IMAP 2014-01-10 14:06:53 -05:00
Ludovic Marcotte 13721b961b Add an easy way to get the personal contact folder, just like we have for calendars 2014-01-10 14:03:50 -05:00
Ludovic Marcotte 689a1e94e0 Sample Active Sync configuration 2014-01-10 14:02:32 -05:00
Ludovic Marcotte afcd92fb71 Load the ActiveSync bundle code and bind it 2014-01-10 14:01:39 -05:00
Ludovic Marcotte 7260c07628 More cleanups 2014-01-09 21:10:48 -05:00
Ludovic Marcotte a24d809e40 Minor code/copyright/authors cleanups 2014-01-09 21:06:31 -05:00
Ludovic Marcotte ed97407578 Dropped old data types 2014-01-09 20:42:16 -05:00
Ludovic Marcotte ca541d7299 Cleanups in conf file 2014-01-09 20:41:16 -05:00
Ludovic Marcotte 2d683ffc77 Always capitalize HTTP headers 2014-01-09 20:40:25 -05:00
Francis Lachapelle d603a8672e Consider 'background' attribute as unsafe
When loading a message, background attributes will be disabled if the
user as chosen to not automatically load external images.

Fixes #2437
2014-01-09 09:15:49 -05:00
Francis Lachapelle d51e1da57f Increase height of signature editor 2014-01-08 15:02:41 -05:00
Francis Lachapelle 80fd439dea Fix message forwarding as attachment
Restored the filename of the message source in the body part
content-disposition header.
Also forced the mail to be saved to the mailstore immediately in order
to have a clickable link to the attached message.
2014-01-08 14:40:39 -05:00
Francis Lachapelle a0d7f184fe Update French translation 2014-01-07 11:51:35 -05:00
Francis Lachapelle fe2826ca76 Draft: Improve error handling when attaching files 2014-01-07 11:11:39 -05:00
Francis Lachapelle ff9ea3b779 Don't alter the draft when saving it
We must not extract inline HTML images when simply saving a draft. The
images extraction process must only be performed when sending the
message.
2014-01-07 10:28:53 -05:00
Francis Lachapelle e70793e7ae Don't follow link of attachment not yet uploaded 2014-01-06 15:09:09 -05:00
Francis Lachapelle 0fdea48ce8 Restore CSS of disabled menu options 2014-01-06 15:08:45 -05:00
Francis Lachapelle 2b53705d44 Untabify 2014-01-06 14:32:58 -05:00
Francis Lachapelle b716331d8e Append tags when using a sanitizerContentHandler 2014-01-06 14:23:11 -05:00
Jean Raby 586d66b113 Updated description of SOGoUIAdditionalJSFiles
Document that the files must be placed under the  WebServerResources directory
2014-01-06 13:28:47 -05:00
Francis Lachapelle 5756defbf1 Mail editor: don't give focus to file input field. 2014-01-06 11:10:28 -05:00
Francis Lachapelle 7130cec4d1 Move & copy messages between different accounts 2014-01-03 16:57:37 -05:00
Francis Lachapelle 009cfccb2c Fix JS error when saving/sending plain text msg 2014-01-03 14:33:27 -05:00
Francis Lachapelle 09e14df79b Preferences: fix display of calendar categories 2014-01-03 14:32:48 -05:00
Francis Lachapelle ba29e7620d Update French translation 2014-01-03 14:32:01 -05:00
Francis Lachapelle 32516b162e Update textarea before saving/sending HTML message 2013-12-31 15:52:15 -05:00
Francis Lachapelle a8e780516b Fix display of "edit draft" and "load images"
The buttons were placed one over the other.
2013-12-23 15:54:22 -05:00
Francis Lachapelle bd7ad5be16 Fix initialization of arrays in NSString+Mail.m 2013-12-23 15:51:36 -05:00
Francis Lachapelle bed57af015 Improve display of linked attachments 2013-12-20 16:18:19 -05:00
Francis Lachapelle 5f369f201d Add links to download one or all attachments
Also removed the contextual menu over file attachments and changed the
label color when moving over the file attachments.
2013-12-20 15:41:18 -05:00
Francis Lachapelle dc21c723f6 Move method fetchFileAttachmentKeys from category
Moved fetchFileAttachmentKeys from SOGoDraftObjectExtensions to
SOGoDraftObject. Renamed fetchAttachmentIds to fetchFileAttachmentIds
for consistency.
2013-12-20 15:20:16 -05:00
Francis Lachapelle 1f7994d1bf Respect locale in time format of attendees window 2013-12-18 22:18:08 -05:00
Francis Lachapelle 7369a82bab Improve upload of attachments to messages 2013-12-18 22:18:08 -05:00
Francis Lachapelle 1a900b05d9 DraftObject: return more attachments attributes 2013-12-18 22:18:08 -05:00
Francis Lachapelle a8e3418a4c Use the UIxMailSizeFormatter in messages listing 2013-12-18 22:18:08 -05:00
Francis Lachapelle 59ce12a51b Load XMLHttpRequest conditionally (< IE9) 2013-12-18 22:18:08 -05:00
Ludovic Marcotte a1bec0e995 Merge branch 'master' of https://github.com/inverse-inc/sogo 2013-12-16 17:48:50 -05:00
Ludovic Marcotte 08ab36244c Improved the logic behind refusing too-many submitted mails. 2013-12-16 17:48:23 -05:00
Jean Raby 9ea880e80b fix backup path 2013-12-11 14:36:28 -05:00
Ludovic Marcotte 7d0a9aa1b7 Cleanups. 2013-12-10 20:09:32 -05:00
Jean Raby 2fa654fadb sogo.conf: fix typo and add AD/Samba4 example 2013-12-10 15:55:44 -05:00
Ludovic Marcotte 4a98e5b521 Don't append unknown objects to the REPORT result. 2013-12-09 10:31:34 -05:00
Francis Lachapelle e5103faed4 Update Finnish translation 2013-12-05 21:33:09 -05:00
Francis Lachapelle f9ad9ea815 Bump version to 2.1.2 2013-12-05 21:10:03 -05:00
Francis Lachapelle cfbd53e374 Fix initialization of preferences module
Don't try to initialize the tabs controller on the mail options tab if
the mail module is disabled.
2013-12-05 09:00:01 -05:00
Jean Raby f2beabec88 document organization and country ldap mapping 2013-12-04 19:50:22 -05:00
Jean Raby eaa0fb3cf1 Update NEWS CKEditor is in 2.1.1b 2013-12-04 11:11:10 -05:00
Jean Raby db56d1fa6c Bump version to 2.1.1b + adjust NEWS 2013-12-04 10:33:48 -05:00
Francis Lachapelle 37de8c6141 CKEditor: don't filter tags 2013-12-02 13:42:34 -05:00
Francis Lachapelle b0eb34f6b7 Add 'div' plugin to CKEditor 2013-12-02 11:58:28 -05:00
Francis Lachapelle 1cf696f57c Mail composition: add text part before html part
Fixes #2512
2013-11-25 09:52:18 -05:00
Francis Lachapelle 2114a48222 Update NEWS file 2013-11-22 15:03:57 -05:00
Francis Lachapelle 384d998c47 Cleanup wox templates 2013-11-22 14:42:16 -05:00
Francis Lachapelle 2211f6d168 Move mail tags strings to UI/Common 2013-11-22 14:39:24 -05:00
Ludovic Marcotte 32ba01315f Init local variable to avoid potential crasher. 2013-11-22 11:29:24 -05:00
Francis Lachapelle 682ed767d9 Fix the Sieve filters editor with new mail flags 2013-11-21 08:52:55 -05:00
Jean Raby 5536f8967e don't escape html in label names 2013-11-21 07:11:05 -05:00
Ludovic Marcotte df3e9033f3 Added calendar default reminder support. 2013-11-20 17:42:11 -05:00
Francis Lachapelle f167475c91 Update CKEditor to version 4.3.0 2013-11-20 11:17:42 -05:00
Ludovic Marcotte e4aedbac08 <img src=data...> conversion to file attachments + CIDs. 2013-11-20 08:56:29 -05:00
Jean Raby 6587f4f193 Update ChangeLog 2013-11-19 13:59:20 -05:00
Francis Lachapelle c8a4ea5548 Update translations 2013-11-19 13:57:18 -05:00
Jean Raby 148fd4936c Update Version to 2.1.1 and update news 2013-11-19 13:43:45 -05:00
Jean Raby a7fef39448 Update to 2.1.1 2013-11-19 13:43:22 -05:00
Francis Lachapelle 5a3d0d27e0 Fix bug following mail tags management CSS changes 2013-11-19 13:39:48 -05:00
Ludovic Marcotte eb9111b5fa Updated news for the recent bug fix 2013-11-19 11:40:33 -05:00
Ludovic Marcotte eb7d1f08bc Fix for bug #2482 2013-11-19 11:39:45 -05:00
Ludovic Marcotte 854fed529c Added SOGoMailAuxiliaryUserAccountsEnabled 2013-11-19 09:52:53 -05:00
Jean Raby 3c29e0724d update news file 2013-11-15 16:12:15 -05:00
Jean Raby cebaed9059 Merge branch 'master' of https://github.com/inverse-inc/sogo 2013-11-15 16:09:52 -05:00
Jean Raby aae26602b0 Use raw (utf7) name when checking folder type 2013-11-15 16:04:09 -05:00
Jean Raby 05233d9c53 Use modified utf7 for special folder names 2013-11-15 16:02:59 -05:00
Francis Lachapelle e862194b32 Convert color picker to an inline widget
The colors are now limited to the colors offered in Thunderbird.
2013-11-15 15:50:46 -05:00
Jean Raby 884fbfdb73 Bump copyright and fix whitespace (tab kill) 2013-11-15 13:17:37 -05:00
Ludovic Marcotte c05cf00db7 Update standard tag colors to match TB and improve tags id generation. 2013-11-14 09:00:19 -05:00
Ludovic Marcotte 198db855f6 Specify color in which TB can grok it. 2013-11-13 15:55:25 -05:00
Ludovic Marcotte 1c439c866e Added DAV support for mails labels. 2013-11-13 15:44:57 -05:00
Francis Lachapelle 616ee7c6e4 GUI changes for mail labels management 2013-11-13 14:46:08 -05:00
Ludovic Marcotte 37d3234b60 Added support for dynamic mail labels/tags management.
The CSS in the UIxPreferences remains to be done.
2013-11-11 10:49:58 -05:00
Francis Lachapelle 6a9bcfda68 Update ChangeLog 2013-11-07 14:42:48 -05:00
Francis Lachapelle d0b09ebe35 Update translations 2013-11-07 14:14:39 -05:00
Francis Lachapelle 0361b7dfdb Documentation - bump version to 2.1.0 2013-11-07 11:09:41 -05:00
Francis Lachapelle 38b350382a Update NEWS file 2013-11-07 10:13:30 -05:00
Francis Lachapelle 73141a645e Update translations 2013-11-06 21:36:09 -05:00
Francis Lachapelle f07526423f Fix display of ICal event in message 2013-11-06 15:25:36 -05:00
Francis Lachapelle ba35a4b003 Update CKEditor to version 4.2.2 2013-11-06 11:29:15 -05:00
Ludovic Marcotte 47c4ad5807 Make sure the var is initilized to nil. 2013-10-29 20:58:26 -04:00
Ludovic Marcotte 0f3e31ebf1 Added more tags to skip 2013-10-23 16:37:03 -04:00
Ludovic Marcotte 87261f3280 Fix for bug #2468. 2013-10-23 16:04:37 -04:00
Ludovic Marcotte bd2759ecdf Fix for bug #2433 2013-10-22 11:44:26 -04:00
Ludovic Marcotte be1bcf3c9b Fix for bug #2461 2013-10-22 11:25:24 -04:00
Ludovic Marcotte 053b090aff Fix for bug #2235 2013-10-21 15:37:01 -04:00
Ludovic Marcotte 189f2218a8 Fix for bug #2459 2013-10-21 15:26:43 -04:00
Ludovic Marcotte 656869a4a2 Fix for bug #1328 2013-10-18 13:16:30 -04:00
Ludovic Marcotte 16f62e2393 Fix for bug #2434 2013-10-18 10:30:43 -04:00
Jean Raby 9289615996 Added https vhost example for apple carddav 2013-10-17 11:45:07 -04:00
Jean Raby fdea04c08c Added some verbose logging for expire-autoreply 2013-10-15 10:49:21 -04:00
Jean Raby edca3638ec Fixup backup_dir to use sogo's home directory 2013-10-11 13:41:44 -04:00
Ludovic Marcotte 05990e9a14 Fix for bug 2007 2013-09-30 10:50:27 -04:00
Jean Raby 3cce9b2012 Fix file permissions 2013-09-30 09:39:29 -04:00
Ludovic Marcotte 7dc65af300 Fix for bug #2386 2013-09-27 15:54:11 -04:00
Ludovic Marcotte 84e999229b Fix for bug #2270 2013-09-27 15:36:46 -04:00
Francis Lachapelle 3dbfb0ed2d Add Underline option to HTML editor 2013-09-27 14:43:05 -04:00
Francis Lachapelle d1f3417c3a Update CKEditor to version 4.2.1
And added the table-related modules.
2013-09-27 14:25:22 -04:00
Ludovic Marcotte 7c7031333e Fix for bug #2221 2013-09-27 10:00:39 -04:00
Jean Raby 1e48481426 Updated description/default value for WOPort 2013-09-26 08:51:42 -04:00
Jean Raby 8ae1624604 Added --noexpiry for administrator 2013-09-26 08:49:17 -04:00
Ludovic Marcotte 7166f5a597 Fix for bug #2399 2013-09-25 16:02:13 -04:00
Ludovic Marcotte 55052ea36f Fix for bug #2240 2013-09-25 14:40:48 -04:00
Ludovic Marcotte 99d38417cc Fix for bug #2354 2013-09-25 13:51:42 -04:00
Ludovic Marcotte 29eed182a7 Updated the OpenChange code related to UTF-7 changes for IMAP folders 2013-09-25 10:41:07 -04:00
Ludovic Marcotte 744610dbe1 Fixed tests regarding new WebDAV sync responses 2013-09-25 08:46:34 -04:00
Ludovic Marcotte d2b739d261 Fix for bug #2318 2013-09-24 16:01:23 -04:00
Ludovic Marcotte 2ba8254ecc Fix for bug #1275 2013-09-24 09:29:46 -04:00
Jean Raby 28e600a4e6 Set default listening address to 127.0.0.1:20000
No reason to listen on 0.0.0.0 by default
2013-09-20 15:37:34 -04:00
Ludovic Marcotte ab6e4841ba Merge branch 'master' of https://github.com/inverse-inc/sogo
Conflicts:
	NEWS
2013-09-19 16:14:41 -04:00
Ludovic Marcotte 91f1ab6a60 Fix for bug #2217 2013-09-19 16:14:08 -04:00
Jean Raby 32a534919d update NEWS. ldap fixes 2013-09-19 11:11:29 -04:00
Ludovic Marcotte 5b77c2b724 Stability fix when we're untable to determine the message class type 2013-09-19 10:49:42 -04:00
Ludovic Marcotte 70086e5ee6 Fix for bug #1935 2013-09-19 09:56:28 -04:00
Ludovic Marcotte 7ddc1b9e2d Avoid type-issues generating wrong GlobCnt - leading to OpenChange crashes during the sync process. 2013-09-18 14:03:07 -04:00
Francis Lachapelle 6d93db96e4 Update NEWS file 2013-09-17 11:17:40 -04:00
Jean Raby 27445d3b85 update news 2013-09-17 09:27:46 -04:00
Jean Raby 60d6abe542 Use HTTP/1.0 to avoid chunked replies
Fixes^WWorkaround #2408
2013-09-17 09:07:53 -04:00
Ludovic Marcotte baacf8516d Updated NEWS file regarding previous commit 2013-09-16 11:21:23 -04:00
Ludovic Marcotte 46a48faf23 Merge branch 'master' of https://github.com/inverse-inc/sogo 2013-09-16 11:00:40 -04:00
Ludovic Marcotte 193720cfbb Fix for s/mime verification issues with some openssl versions 2013-09-16 10:59:45 -04:00
Jean Raby f40580d632 Merge branch 'master' of https://github.com/inverse-inc/sogo 2013-09-13 11:25:08 -04:00
Jean Raby ca4d89fb08 update with latest fixes 2013-09-13 11:24:16 -04:00
Jean Raby 906985c1f3 Call MSExchangeHostname on SOGoDNSource only
Fixes #2418
2013-09-13 11:19:44 -04:00
Jean Raby de8bf64c70 Local pool when appending contacts to response
Avoids using too much memory when doing a contact lookup with many matches
2013-09-13 11:16:28 -04:00
Jean Raby 0c38a9e555 whitespace tabkill 2013-09-13 11:13:02 -04:00
Francis Lachapelle 3c6c90d434 Reload webmail when changing "remote images" pref 2013-09-13 09:33:28 -04:00
Francis Lachapelle 72a4b075d6 Mail popup: respect "remote inline images" prefs
Fixes #2417
2013-09-12 17:08:02 -04:00
Francis Lachapelle 24c0fb1cc4 Fix change listener on calendar list select input
Fixes #2353
2013-09-12 16:33:44 -04:00
Jean Raby 7241e3e30e Added rewrite rule for apple autoconfiguration url
Rewrite rules are no inherited by virtualhosts when they are declared in conf.d
This means that you'll have to explicitly include SOGo.conf from 000-default
on debian/ubuntu for this redirection to work properly.
2013-09-12 10:14:47 -04:00
Jean Raby 1d705dc00b Next version: 2.1.0 2013-09-10 13:58:04 -04:00
Jean Raby df42ab2a46 Run 3 sogod process by default instead on only 1 2013-09-09 10:07:07 -04:00
Ludovic Marcotte 53f9d0d7f5 Merge branch 'master' of https://github.com/inverse-inc/sogo 2013-09-06 13:49:25 -04:00
Jean Raby f59c77a950 Update news 2013-09-06 13:49:04 -04:00
Ludovic Marcotte cd4abe4b5b Fix for bug 2398 2013-09-06 13:48:44 -04:00
Francis Lachapelle 69b0f9fcbf Mail notifications: Escape HTML in wox templates
We don't escape the values in the classes but in the templates.
2013-09-03 12:05:13 -04:00
Jean Raby dceead3997 Fixup sogo spool cleanup cronjob
Add -user sogo to be on the safe side.
Change call to /bin/rmdir by -delete to avoid error messages.
Find would call rmdir and then do an openat() on the deleted directory,
which would obviously fail.

Fixes #2372
2013-09-03 09:59:01 -04:00
Jean Raby 573c2ec114 updated News 2013-08-29 15:51:05 -04:00
Jean Raby 6a68c255bd Merge branch 'fix/ldap-password-change' 2013-08-29 15:15:07 -04:00
Jean Raby e9d8b729b6 Bump version file to 2.0.8 for nightly builds 2013-08-29 14:34:25 -04:00
Jean Raby 1e7dfc0934 Updated cron sections for credentials files
Added a note regarding password change against AD/Samba4
2013-08-29 14:32:34 -04:00
Jean Raby d7e6648396 Reworked password change logic and add AD support 2013-08-28 17:11:07 -04:00
Jean Raby 65603201f7 ignore pyc files and config.py 2013-08-28 10:05:36 -04:00
Jean Raby 9fd6f75c4e Update crontab for SMTP AUTH credentials 2013-08-28 09:47:10 -04:00
Jean Raby b96f25f99f updated NEWS 2013-08-27 14:44:28 -04:00
Jean Raby d7851999da Merge branch 'fix/email-notif-auth' 2013-08-27 14:37:52 -04:00
Jean Raby e6ab0a590a Support using SMTP AUTH creds for email alarms
Credentials must be supplied using '-p /path/to/credsFile'.
The credentials file should contain a single line with the format 'user:pass'

While there, add a usage message
2013-08-27 13:12:03 -04:00
Jean Raby be531100c6 Use SOGoCredentialsFile to avoid duplicated code 2013-08-27 13:04:08 -04:00
Jean Raby e946a67ddf Special case for auth with SOGoStaticAuthenticator 2013-08-27 13:02:06 -04:00
Jean Raby 2fe87f14fd Add SOGoStaticAuthenticator
New authenticator that is not linked to a SOGoUser.
Will be used for SMTP AUTH by sogo-elalarm-notify.
2013-08-27 12:59:03 -04:00
Jean Raby b2f012cae2 Add SOGoCredentialsFile
New class to read credentials files as used by sogo-tool and sogo-ealarm-notify
2013-08-27 12:56:07 -04:00
Francis Lachapelle 33659aa947 Increase height of alarm editor
Only when email alarms are enabled.
2013-08-27 12:01:41 -04:00
Francis Lachapelle df1ab29872 Fix position of red "now" line
Fixes #2373
2013-08-27 09:06:48 -04:00
Jean Raby 61e59b864e Bump copyright 2013-08-27 08:33:50 -04:00
Francis Lachapelle 0a590ba388 Fix Finnish mail reply/forward templates 2013-08-26 08:59:43 -04:00
Ludovic Marcotte ab92516dd0 Fix for bug #1431 2013-08-09 11:39:15 -04:00
Ludovic Marcotte 7b90b892fc Fix for bug #2385 2013-08-07 08:49:59 -04:00
Jean Raby b654ffb806 add webdavsync-tool.py
first draft of a small tool to simulate a TB calendar sync
2013-08-02 16:56:36 -04:00
Jean Raby 6de689bbe2 Add depth support to CalendarMultiget 2013-08-02 15:41:24 -04:00
Jean Raby 7eb8b9c2c3 Add SxVMemLimit to sogo.conf 2013-08-02 09:51:41 -04:00
Jean Raby 3877f3001f replace xml.dom.ext by xml.dom.minidom 2013-08-01 12:48:42 -04:00
Ludovic Marcotte 4d2c734781 Revert "Try to use a local pool to avoid huge memory consumption"
This reverts commit e57d875e0a.
2013-07-29 14:32:58 -04:00
Ludovic Marcotte e57d875e0a Try to use a local pool to avoid huge memory consumption 2013-07-29 09:43:21 -04:00
Ludovic Marcotte b1df03adc7 Fix for old runtimes. 2013-07-24 10:54:55 -04:00
Francis Lachapelle bd776152db Update ChangeLog 2013-07-23 10:02:13 -04:00
Ludovic Marcotte c6374b52ec Merge branch 'master' of https://github.com/inverse-inc/sogo 2013-07-23 09:26:55 -04:00
Ludovic Marcotte 734c164ae0 Reverted broken patch in #2360 and tried to fix it cleanly 2013-07-23 09:25:24 -04:00
Francis Lachapelle 9f381e768d Update ChangeLog 2013-07-23 08:38:09 -04:00
Ludovic Marcotte b531b6160c Fixed compilation ordering to avoid bug in gnustep-make 2013-07-23 08:31:38 -04:00
Francis Lachapelle 8a041860a0 Update ChangeLog 2013-07-19 13:40:33 -04:00
Francis Lachapelle d5f76ac832 Improve CSS print media 2013-07-19 13:39:18 -04:00
Francis Lachapelle 12b7fea825 Documentation - bump version to 2.0.7 2013-07-19 13:37:13 -04:00
Francis Lachapelle 1c82af8842 Updated pt_BR, cs, nl, de, pl and ru translations 2013-07-19 11:29:10 -04:00
Francis Lachapelle 6cef5245e1 Bump version to 2.0.7 2013-07-19 11:27:17 -04:00
Francis Lachapelle 0069a4200b Handle possible jQuery error with DnD of contacts 2013-07-19 10:51:41 -04:00
Ludovic Marcotte e24c20c48a Reverted patch 2013-07-19 10:11:08 -04:00
Ludovic Marcotte 256b679798 Bug fix for #2366 2013-07-18 11:46:49 -04:00
Francis Lachapelle b85ed0db1c Fix blur of active element on click on a draggable
This bug has yet to be officially part of jQuery UI, therefore this
commit updates jquery-ui to version 1.10.3 patched with commit fcd1caf:

https://github.com/jquery/jquery-ui/commit/fcd1cafac8afe3a947676ec018e844eeada5b9de
2013-07-18 11:32:29 -04:00
Ludovic Marcotte 048bae2fc5 Applied patch from bug #2235 2013-07-18 10:52:37 -04:00
Ludovic Marcotte 19e542396b Applied patch from bug #2360 2013-07-18 10:25:39 -04:00
Francis Lachapelle 249a1fcf14 Bubble box of event should not overlap event cell 2013-07-17 14:57:07 -04:00
Ludovic Marcotte 7dad5ad84e Updated for v2.0.7 2013-07-16 15:20:26 -04:00
Ludovic Marcotte 16105d37b8 Properly handle RFC2231 everywhere 2013-07-16 15:18:04 -04:00
Ludovic Marcotte e08ebd2390 Fix for bugs #2368 and #2369 2013-07-16 11:31:08 -04:00
Francis Lachapelle 03553980fd Update NEWS file and add missing image 2013-07-11 13:55:03 -04:00
Francis Lachapelle 33fd60efb3 Calendar: print gridlines to 15-minute intervals 2013-07-11 13:50:44 -04:00
Francis Lachapelle b8e2255a07 Set the events/tasks list collapsable 2013-07-11 13:46:38 -04:00
Ludovic Marcotte e687dbf155 If the organizer's name is non-existent, use the email address 2013-07-04 13:11:02 -04:00
Jean Raby f42d52743d bump version to 2.0.6b 2013-06-27 11:35:17 -04:00
Jean Raby 70cd64a626 Update ChangeLog 2013-06-27 11:34:06 -04:00
Jean Raby 4359b05da8 updated NEWS 2013-06-27 11:33:44 -04:00
Ludovic Marcotte 25dbd4849d Properly escape the foldername to avoid XSS issues 2013-06-27 11:14:50 -04:00
Jean Raby a2a89e8720 Fix loading of MSExchangeFreeBusySOAPResponseMap 2013-06-26 16:55:39 -04:00
Jean Raby 2581f6c568 Update for 2.0.6a 2013-06-25 09:19:37 -04:00
Jean Raby 20369631c9 Update ChangeLog 2013-06-25 09:17:03 -04:00
Jean Raby 1221da2443 Add CASLogoutRequestMap.plist 2013-06-25 09:12:27 -04:00
Jean Raby f27b8b6a54 Document SOGoCASLogoutEnabled 2013-06-25 09:06:28 -04:00
Jeroen Dekkers 4d8bff5130 Link libSOGo with libdl on systems with glibc 2013-04-14 11:50:28 +02:00
1330 changed files with 55838 additions and 16358 deletions

No files matched your search

+7
View File
@@ -1,6 +1,8 @@
config.make
tags
*._*
*/obj/
*._*
*/*/obj/
*/*/*/obj/
*/*/*.SOGo/
@@ -9,3 +11,8 @@ tags
*.swp
SoObjects/SOGo/SOGo.framework/
SoObjects/SOGo/derived_src/
Tests/*/config.py
*.pyc
._*
Documentation/*.docbook
Documentation/*.pdf
+27 -1
View File
@@ -1,5 +1,5 @@
[main]
host = https://www.transifex.net
host = https://www.transifex.com
[sogo.ui-mailerui]
source_file = UI/MailerUI/English.lproj/Localizable.strings
@@ -235,6 +235,32 @@ trans.sk = SoObjects/Contacts/Slovak.lproj/Localizable.strings
trans.sv = SoObjects/Contacts/Swedish.lproj/Localizable.strings
trans.uk = SoObjects/Contacts/Ukrainian.lproj/Localizable.strings
[sogo.soobjects-mailer]
source_file = SoObjects/Mailer/English.lproj/Localizable.strings
source_lang = en
trans.ar = SoObjects/Mailer/Arabic.lproj/Localizable.strings
trans.ca = SoObjects/Mailer/Catalan.lproj/Localizable.strings
trans.cs = SoObjects/Mailer/Czech.lproj/Localizable.strings
trans.cy = SoObjects/Mailer/Welsh.lproj/Localizable.strings
trans.da_DK = SoObjects/Mailer/Danish.lproj/Localizable.strings
trans.de = SoObjects/Mailer/German.lproj/Localizable.strings
trans.es_AR = SoObjects/Mailer/SpanishArgentina.lproj/Localizable.strings
trans.es_ES = SoObjects/Mailer/SpanishSpain.lproj/Localizable.strings
trans.fi = SoObjects/Mailer/Finnish.lproj/Localizable.strings
trans.fr = SoObjects/Mailer/French.lproj/Localizable.strings
trans.hu = SoObjects/Mailer/Hungarian.lproj/Localizable.strings
trans.is = SoObjects/Mailer/Icelandic.lproj/Localizable.strings
trans.it = SoObjects/Mailer/Italian.lproj/Localizable.strings
trans.nb_NO = SoObjects/Mailer/NorwegianBokmal.lproj/Localizable.strings
trans.nl = SoObjects/Mailer/Dutch.lproj/Localizable.strings
trans.nn_NO = SoObjects/Mailer/NorwegianNynorsk.lproj/Localizable.strings
trans.pl = SoObjects/Mailer/Polish.lproj/Localizable.strings
trans.pt_BR = SoObjects/Mailer/BrazilianPortuguese.lproj/Localizable.strings
trans.ru = SoObjects/Mailer/Russian.lproj/Localizable.strings
trans.sk = SoObjects/Mailer/Slovak.lproj/Localizable.strings
trans.sv = SoObjects/Mailer/Swedish.lproj/Localizable.strings
trans.uk = SoObjects/Mailer/Ukrainian.lproj/Localizable.strings
[sogo.ui-mailpartviewers]
source_file = UI/MailPartViewers/English.lproj/Localizable.strings
source_lang = en
+40
View File
@@ -0,0 +1,40 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <Foundation/NSObject.h>
@interface ActiveSyncProduct : NSObject
{
}
@end
@implementation ActiveSyncProduct
@end /* ActiveSyncProduct */
+42
View File
@@ -0,0 +1,42 @@
# GNUstep makefile
include common.make
BUNDLE_NAME = ActiveSync
ActiveSync_PRINCIPAL_CLASS = ActiveSyncProduct
ActiveSync_OBJC_FILES = \
ActiveSyncProduct.m \
iCalAlarm+ActiveSync.m \
iCalEvent+ActiveSync.m \
iCalRecurrenceRule+ActiveSync.m \
iCalTimeZone+ActiveSync.m \
iCalToDo+ActiveSync.m \
NSCalendarDate+ActiveSync.m \
NSData+ActiveSync.m \
NSDate+ActiveSync.m \
NGDOMElement+ActiveSync.m \
NGMimeMessage+ActiveSync.m \
NGVCard+ActiveSync.m \
NSArray+SyncCache.m \
NSString+ActiveSync.m \
SOGoActiveSyncDispatcher.m \
SOGoActiveSyncDispatcher+Sync.m \
SOGoMailObject+ActiveSync.m \
SOGoSyncCacheObject.m \
SoObjectWebDAVDispatcher+ActiveSync.m
ActiveSync_RESOURCE_FILES += \
product.plist
ADDITIONAL_OBJCFLAGS += -Wno-deprecated-declarations
ADDITIONAL_INCLUDE_DIRS += -I../SOPE/ -I../SoObjects/
ADDITIONAL_LIB_DIRS += -L../SOPE/GDLContentStore/obj/ -L../SOPE/NGCards/obj/
ADDITIONAL_INCLUDE_DIRS += -I/usr/include/libwbxml-1.0/
ADDITIONAL_LDFLAGS += -Wl,--no-as-needed -lwbxml2
-include GNUmakefile.preamble
include $(GNUSTEP_MAKEFILES)/bundle.make
-include GNUmakefile.postamble
+1
View File
@@ -0,0 +1 @@
# compilation settings
+25
View File
@@ -0,0 +1,25 @@
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+44
View File
@@ -0,0 +1,44 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __NGDOMELEMENTACTIVESYNC_H__
#define __NGDOMELEMENTACTIVESYNC_H__
#import <DOM/DOMElement.h>
#import <DOM/DOMProtocols.h>
@class NSDictionary;
@interface NGDOMElement (ActiveSync)
- (NSDictionary *) applicationData;
@end
#endif // NGDOMELEMENTACTIVESYNC
+190
View File
@@ -0,0 +1,190 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "NGDOMElement+ActiveSync.h"
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
static NSArray *asElementArray = nil;
@implementation NGDOMElement (ActiveSync)
- (BOOL) isTextNode
{
id <DOMNodeList> children;
id <DOMElement> element;
int i;
if ([self nodeType] == DOM_TEXT_NODE)
return YES;
children = [self childNodes];
for (i = 0; i < [children length]; i++)
{
element = [children objectAtIndex: i];
if ([element nodeType] != DOM_TEXT_NODE)
return NO;
}
return YES;
}
//
// We must handle "inner data" like this:
//
// <ApplicationData>
// <Flag xmlns="Email:">
// <FlagStatus>2</FlagStatus>
// <FlagType>Flag for follow up</FlagType>
// </Flag>
// </ApplicationData>
//
// and stuff like that:
//
// <Attendees xmlns="Calendar:">
// <Attendee>
// <Attendee_Email>sogo1@example.com</Attendee_Email>
// <Attendee_Name>John Doe</Attendee_Name>
// <Attendee_Status>5</Attendee_Status>
// <Attendee_Type>1</Attendee_Type>
// </Attendee>
// <Attendee>
// <Attendee_Email>sogo2@example.com</Attendee_Email>
// <Attendee_Name>Balthazar César</Attendee_Name>
// <Attendee_Status>5</Attendee_Status>
// <Attendee_Type>1</Attendee_Type>
// </Attendee>
// <Attendee>
// <Attendee_Email>sogo3@example.com</Attendee_Email>
// <Attendee_Name>Wolfgang Fritz</Attendee_Name>
// <Attendee_Status>5</Attendee_Status>
// <Attendee_Type>1</Attendee_Type>
// </Attendee>
// </Attendees>
//
- (NSDictionary *) applicationData
{
NSMutableDictionary *data;
id <DOMNodeList> children;
id <DOMElement> element;
int i, count;
if (!asElementArray)
asElementArray = [[NSArray alloc] initWithObjects: @"Attendee", @"Category", nil];
data = [NSMutableDictionary dictionary];
children = [self childNodes];
for (i = 0; i < [children length]; i++)
{
element = [children objectAtIndex: i];
if ([element nodeType] == DOM_ELEMENT_NODE)
{
NSString *tag;
id value;
tag = [element tagName];
count = [(NSArray *)[element childNodes] count];
// We check if the node is a text one or if all its
// children are text nodes. This is important to avoid side-effects
// in SOPE where "foo & bar" would result into 3 childnodes instead
// of just one.
if ([(id)element isTextNode])
{
value = [(id)element textValue];
}
// Handle inner data - see above for samples
else
{
NSMutableArray *innerElements;
id <DOMElement> innerElement;
NSArray *childNodes;
NSString *innerTag;
BOOL same;
int j;
childNodes = (NSArray *)[element childNodes];
innerElements = [NSMutableArray array];
innerTag = nil;
same = YES;
for (j = 1; j < count; j++)
{
innerElement = [childNodes objectAtIndex: j];
if ([innerElement nodeType] == DOM_ELEMENT_NODE)
{
if (!innerTag)
innerTag = [innerElement tagName];
if ([innerTag isEqualToString: [innerElement tagName]])
{
if ([(id)innerElement isTextNode])
[innerElements addObject: [(NGDOMElement *)innerElement textValue]];
else
[innerElements addObject: [(NGDOMElement *)innerElement applicationData]];
}
else
{
same = NO;
break;
}
}
}
if (same && [asElementArray containsObject: innerTag])
value = innerElements;
else
{
value = [(NGDOMElement *)element applicationData];
// Don't set empty values like Foo = {}
if (![value count])
value = nil;
}
}
if (value && tag)
[data setObject: value forKey: tag];
} // if ([element nodeType] == DOM_ELEMENT_NODE)
}
return data;
}
@end
+43
View File
@@ -0,0 +1,43 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __NGMIMEMESSAGEACTIVESYNC_H__
#define __NGMIMEMESSAGEACTIVESYNC_H__
#import <NGMail/NGMimeMessage.h>
@class NSArray;
@interface NGMimeMessage (ActiveSync)
- (NSArray *) allRecipients;
@end
#endif
+75
View File
@@ -0,0 +1,75 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "NGMimeMessage+ActiveSync.h"
#import <Foundation/NSArray.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSString.h>
#import <NGMail/NGMailAddress.h>
#import <NGMail/NGMailAddressParser.h>
#import <SOGo/NSString+Utilities.h>
@implementation NGMimeMessage (ActiveSync)
- (NSArray *) allRecipients
{
NSEnumerator *enumerator, *addressList;
NSMutableArray *recipients;
NGMailAddressParser *parser;
NGMailAddress *address;
NSString *s;
recipients = [NSMutableArray array];
enumerator = [[self headersForKey: @"to"] objectEnumerator];
while ((s = [enumerator nextObject]))
{
parser = [NGMailAddressParser mailAddressParserWithString: s];
addressList = [[parser parseAddressList] objectEnumerator];
while ((address = [addressList nextObject]))
[recipients addObject: [address address]];
}
enumerator = [[self headersForKey: @"cc"] objectEnumerator];
while ((s = [enumerator nextObject]))
{
parser = [NGMailAddressParser mailAddressParserWithString: s];
addressList = [[parser parseAddressList] objectEnumerator];
while ((address = [addressList nextObject]))
[recipients addObject: [address address]];
}
return recipients;
}
@end
+47
View File
@@ -0,0 +1,47 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __NGVCARDACTIVESYNC_H__
#define __NGVCARDACTIVESYNC_H__
#import <NGCards/NGVCard.h>
@class NSDictionary;
@class NSString;
@class WOContext;
@interface NGVCard (ActiveSync)
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context;
- (void) takeActiveSyncValues: (NSDictionary *) theValues
inContext: (WOContext *) context;
@end
#endif
+360
View File
@@ -0,0 +1,360 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "NGVCard+ActiveSync.h"
#import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <NGExtensions/NSString+misc.h>
#import <NGCards/CardElement.h>
#import <Contacts/NGVCard+SOGo.h>
#import <SOGo/NSString+Utilities.h>
#include "NSDate+ActiveSync.h"
#include "NSString+ActiveSync.h"
@implementation NGVCard (ActiveSync)
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context
{
NSArray *emails, *addresses, *categories, *elements;
CardElement *n, *homeAdr, *workAdr;
NSMutableString *s;
NSString *url;
id o;
int i;
s = [NSMutableString string];
n = [self n];
if ((o = [n flattenedValueAtIndex: 0 forKey: @""]))
[s appendFormat: @"<LastName xmlns=\"Contacts:\">%@</LastName>", [o activeSyncRepresentationInContext: context]];
if ((o = [n flattenedValueAtIndex: 1 forKey: @""]))
[s appendFormat: @"<FirstName xmlns=\"Contacts:\">%@</FirstName>", [o activeSyncRepresentationInContext: context]];
if ((o = [self workCompany]))
[s appendFormat: @"<CompanyName xmlns=\"Contacts:\">%@</CompanyName>", [o activeSyncRepresentationInContext: context]];
if ((o = [[self org] flattenedValueAtIndex: 1 forKey: @""]))
[s appendFormat: @"<Department xmlns=\"Contacts:\">%@</Department>", [o activeSyncRepresentationInContext: context]];
categories = [self categories];
if ([categories count])
{
[s appendFormat: @"<Categories xmlns=\"Contacts:\">"];
for (i = 0; i < [categories count]; i++)
{
[s appendFormat: @"<Category xmlns=\"Contacts:\">%@</Category>", [[categories objectAtIndex: i] activeSyncRepresentationInContext: context]];
}
[s appendFormat: @"</Categories>"];
}
elements = [self childrenWithTag: @"url"
andAttribute: @"type"
havingValue: @"work"];
if ([elements count] > 0)
{
url = [[elements objectAtIndex: 0] flattenedValuesForKey: @""];
[s appendFormat: @"<WebPage xmlns=\"Contacts:\">%@</WebPage>", [url activeSyncRepresentationInContext: context]];
}
if ((o = [[self uniqueChildWithTag: @"x-aim"] flattenedValuesForKey: @""]))
[s appendFormat: @"<IMAddress xmlns=\"Contacts:\">%@</IMAddress>", [o activeSyncRepresentationInContext: context]];
if ((o = [self nickname]))
[s appendFormat: @"<NickName xmlns=\"Contacts:\">%@</NickName>", [o activeSyncRepresentationInContext: context]];
if ((o = [self title]))
[s appendFormat: @"<JobTitle xmlns=\"Contacts:\">%@</JobTitle>", [o activeSyncRepresentationInContext: context]];
if ((o = [self preferredEMail]))
[s appendFormat: @"<Email1Address xmlns=\"Contacts:\">%@</Email1Address>", o];
// Secondary email addresses (2 and 3)
emails = [self secondaryEmails];
for (i = 0; i < [emails count]; i++)
{
o = [[emails objectAtIndex: i] flattenedValuesForKey: @""];
[s appendFormat: @"<Email%dAddress xmlns=\"Contacts:\">%@</Email%dAddress>", i+2, o, i+2];
if (i == 1)
break;
}
// Telephone numbers
if ((o = [self workPhone]) && [o length])
[s appendFormat: @"<BusinessPhoneNumber xmlns=\"Contacts:\">%@</BusinessPhoneNumber>", [o activeSyncRepresentationInContext: context]];
if ((o = [self homePhone]) && [o length])
[s appendFormat: @"<HomePhoneNumber xmlns=\"Contacts:\">%@</HomePhoneNumber>", [o activeSyncRepresentationInContext: context]];
if ((o = [self fax]) && [o length])
[s appendFormat: @"<BusinessFaxNumber xmlns=\"Contacts:\">%@</BusinessFaxNumber>", [o activeSyncRepresentationInContext: context]];
if ((o = [self mobile]) && [o length])
[s appendFormat: @"<MobilePhoneNumber xmlns=\"Contacts:\">%@</MobilePhoneNumber>", [o activeSyncRepresentationInContext: context]];
if ((o = [self pager]) && [o length])
[s appendFormat: @"<PagerNumber xmlns=\"Contacts:\">%@</PagerNumber>", [o activeSyncRepresentationInContext: context]];
// Home Address
addresses = [self childrenWithTag: @"adr"
andAttribute: @"type"
havingValue: @"home"];
if ([addresses count])
{
homeAdr = [addresses objectAtIndex: 0];
if ((o = [homeAdr flattenedValueAtIndex: 2 forKey: @""]))
[s appendFormat: @"<HomeStreet xmlns=\"Contacts:\">%@</HomeStreet>", [o activeSyncRepresentationInContext: context]];
if ((o = [homeAdr flattenedValueAtIndex: 3 forKey: @""]))
[s appendFormat: @"<HomeCity xmlns=\"Contacts:\">%@</HomeCity>", [o activeSyncRepresentationInContext: context]];
if ((o = [homeAdr flattenedValueAtIndex: 4 forKey: @""]))
[s appendFormat: @"<HomeState xmlns=\"Contacts:\">%@</HomeState>", [o activeSyncRepresentationInContext: context]];
if ((o = [homeAdr flattenedValueAtIndex: 5 forKey: @""]))
[s appendFormat: @"<HomePostalCode xmlns=\"Contacts:\">%@</HomePostalCode>", [o activeSyncRepresentationInContext: context]];
if ((o = [homeAdr flattenedValueAtIndex: 6 forKey: @""]))
[s appendFormat: @"<HomeCountry xmlns=\"Contacts:\">%@</HomeCountry>", [o activeSyncRepresentationInContext: context]];
}
// Work Address
addresses = [self childrenWithTag: @"adr"
andAttribute: @"type"
havingValue: @"work"];
if ([addresses count])
{
workAdr = [addresses objectAtIndex: 0];
if ((o = [workAdr flattenedValueAtIndex: 2 forKey: @""]))
[s appendFormat: @"<BusinessStreet xmlns=\"Contacts:\">%@</BusinessStreet>", [o activeSyncRepresentationInContext: context]];
if ((o = [workAdr flattenedValueAtIndex: 3 forKey: @""]))
[s appendFormat: @"<BusinessCity xmlns=\"Contacts:\">%@</BusinessCity>", [o activeSyncRepresentationInContext: context]];
if ((o = [workAdr flattenedValueAtIndex: 4 forKey: @""]))
[s appendFormat: @"<BusinessState xmlns=\"Contacts:\">%@</BusinessState>", [o activeSyncRepresentationInContext: context]];
if ((o = [workAdr flattenedValueAtIndex: 5 forKey: @""]))
[s appendFormat: @"<BusinessPostalCode xmlns=\"Contacts:\">%@</BusinessPostalCode>", [o activeSyncRepresentationInContext: context]];
if ((o = [workAdr flattenedValueAtIndex: 6 forKey: @""]))
[s appendFormat: @"<BusinessCountry xmlns=\"Contacts:\">%@</BusinessCountry>", [o activeSyncRepresentationInContext: context]];
}
// Other, less important fields
if ((o = [self birthday]))
[s appendFormat: @"<Birthday xmlns=\"Contacts:\">%@</Birthday>", [o activeSyncRepresentationInContext: context]];
if ((o = [self note]))
{
o = [o activeSyncRepresentationInContext: context];
[s appendString: @"<Body xmlns=\"AirSyncBase:\">"];
[s appendFormat: @"<Type>%d</Type>", 1];
[s appendFormat: @"<EstimatedDataSize>%d</EstimatedDataSize>", [o length]];
[s appendFormat: @"<Truncated>%d</Truncated>", 0];
[s appendFormat: @"<Data>%@</Data>", o];
[s appendString: @"</Body>"];
}
if ((o = [self photo]))
[s appendFormat: @"<Picture xmlns=\"Contacts:\">%@</Picture>", o];
return s;
}
//
//
//
- (void) takeActiveSyncValues: (NSDictionary *) theValues
inContext: (WOContext *) context
{
CardElement *element;
id o;
// Contact's note
if ((o = [[theValues objectForKey: @"Body"] objectForKey: @"Data"]))
[self setNote: o];
// Categories
if ((o = [theValues objectForKey: @"Categories"]) && [o length])
[self setCategories: o];
// Birthday
if ((o = [theValues objectForKey: @"Birthday"]))
{
o = [o calendarDate];
[self setBday: [o descriptionWithCalendarFormat: @"%Y-%m-%d"]];
}
//
// Business address information
//
// BusinessStreet
// BusinessCity
// BusinessPostalCode
// BusinessState
// BusinessCountry
//
element = [self elementWithTag: @"adr" ofType: @"work"];
[element setSingleValue: @""
atIndex: 1 forKey: @""];
[element setSingleValue: [theValues objectForKey: @"BusinessStreet"]
atIndex: 2 forKey: @""];
[element setSingleValue: [theValues objectForKey: @"BusinessCity"]
atIndex: 3 forKey: @""];
[element setSingleValue: [theValues objectForKey: @"BusinessState"]
atIndex: 4 forKey: @""];
[element setSingleValue: [theValues objectForKey: @"BusinessPostalCode"]
atIndex: 5 forKey: @""];
[element setSingleValue: [theValues objectForKey: @"BusinessCountry"]
atIndex: 6 forKey: @""];
//
// Home address information
//
// HomeStreet
// HomeCity
// HomePostalCode
// HomeState
// HomeCountry
//
element = [self elementWithTag: @"adr" ofType: @"home"];
[element setSingleValue: @""
atIndex: 1 forKey: @""];
[element setSingleValue: [theValues objectForKey: @"HomeStreet"]
atIndex: 2 forKey: @""];
[element setSingleValue: [theValues objectForKey: @"HomeCity"]
atIndex: 3 forKey: @""];
[element setSingleValue: [theValues objectForKey: @"HomeState"]
atIndex: 4 forKey: @""];
[element setSingleValue: [theValues objectForKey: @"HomePostalCode"]
atIndex: 5 forKey: @""];
[element setSingleValue: [theValues objectForKey: @"HomeCountry"]
atIndex: 6 forKey: @""];
// Company's name
if ((o = [theValues objectForKey: @"CompanyName"]))
[self setOrg: o units: nil];
// Department
if ((o = [theValues objectForKey: @"Department"]))
[self setOrg: nil units: [NSArray arrayWithObjects:o,nil]];
// Email addresses
if ((o = [theValues objectForKey: @"Email1Address"]))
{
element = [self elementWithTag: @"email" ofType: @"work"];
[element setSingleValue: [o pureEMailAddress] forKey: @""];
}
if ((o = [theValues objectForKey: @"Email2Address"]))
{
element = [self elementWithTag: @"email" ofType: @"home"];
[element setSingleValue: [o pureEMailAddress] forKey: @""];
}
// SOGo currently only supports 2 email addresses ... but AS clients might send 3
// FIXME: revise this when the GUI revamp is done in SOGo
if ((o = [theValues objectForKey: @"Email3Address"]))
{
element = [self elementWithTag: @"email" ofType: @"three"];
[element setSingleValue: [o pureEMailAddress] forKey: @""];
}
// Formatted name
// MiddleName
// Suffix (II)
// Title (Mr.)
[self setFn: [theValues objectForKey: @"FileAs"]];
[self setNWithFamily: [theValues objectForKey: @"LastName"]
given: [theValues objectForKey: @"FirstName"]
additional: nil prefixes: nil suffixes: nil];
// IM information
[[self uniqueChildWithTag: @"x-aim"]
setSingleValue: [theValues objectForKey: @"IMAddress"]
forKey: @""];
//
// Phone numbrrs
//
element = [self elementWithTag: @"tel" ofType: @"work"];
[element setSingleValue: [theValues objectForKey: @"BusinessPhoneNumber"] forKey: @""];
element = [self elementWithTag: @"tel" ofType: @"home"];
[element setSingleValue: [theValues objectForKey: @"HomePhoneNumber"] forKey: @""];
element = [self elementWithTag: @"tel" ofType: @"cell"];
[element setSingleValue: [theValues objectForKey: @"MobilePhoneNumber"] forKey: @""];
element = [self elementWithTag: @"tel" ofType: @"fax"];
[element setSingleValue: [theValues objectForKey: @"BusinessFaxNumber"] forKey: @""];
element = [self elementWithTag: @"tel" ofType: @"pager"];
[element setSingleValue: [theValues objectForKey: @"PagerNumber"] forKey: @""];
// Job's title
if ((o = [theValues objectForKey: @"JobTitle"]))
[self setTitle: o];
// WebPage (work)
if ((o = [theValues objectForKey: @"WebPage"]))
[[self elementWithTag: @"url" ofType: @"work"]
setSingleValue: o forKey: @""];
if ((o = [theValues objectForKey: @"NickName"]))
[self setNickname: o];
if ((o = [theValues objectForKey: @"Picture"]))
[self setPhoto: o];
}
@end
+49
View File
@@ -0,0 +1,49 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __NSARRAYSYNCCACHE_H__
#define __NSARRAYSYNCCACHE_H__
#import <Foundation/NSArray.h>
@class NSDictionary;
@interface NSMutableArray (SyncCache)
- (id) initWithDictionary: (NSDictionary *) theDictionary;
@end
@interface NSArray (SyncCache)
- (NSDictionary *) dictionaryValue;
@end
#endif
+84
View File
@@ -0,0 +1,84 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "NSArray+SyncCache.h"
#import <Foundation/NSDictionary.h>
#include "SOGoSyncCacheObject.h"
@implementation NSMutableArray (SyncCache)
- (id) initWithDictionary: (NSDictionary *) theDictionary
{
SOGoSyncCacheObject *o;
NSArray *allKeys;
id key;
int i;
self = [self initWithCapacity: [theDictionary count]];
allKeys = [theDictionary allKeys];
for (i = 0; i < [allKeys count]; i++)
{
key = [allKeys objectAtIndex: i];
o = [SOGoSyncCacheObject syncCacheObjectWithUID: key
sequence: [theDictionary objectForKey: key]];
[self addObject: o];
}
return self;
}
@end
//
//
//
@implementation NSArray (SyncCache)
- (NSDictionary *) dictionaryValue
{
NSMutableDictionary *d;
SOGoSyncCacheObject *o;
int i;
d = [NSMutableDictionary dictionary];
for (i = 0; i < [self count]; i++)
{
o = [self objectAtIndex: i];
[d setObject: [o sequence] forKey: [o uid]];
}
return d;
}
@end
+43
View File
@@ -0,0 +1,43 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __NSCALENDARDATEACTIVESYNC_H__
#define __NSCALENDARDATEACTIVESYNC_H__
#import <Foundation/NSCalendarDate.h>
@class NSString;
@interface NSCalendarDate (ActiveSync)
+ (NSCalendarDate *) dateFromFilterType: (NSString *) theFilterType;
@end
#endif
+87
View File
@@ -0,0 +1,87 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "NSCalendarDate+ActiveSync.h"
#import <Foundation/NSString.h>
#import <Foundation/NSTimeZone.h>
#define ONE_DAY 86400
@implementation NSCalendarDate (ActiveSync)
//
// See http://msdn.microsoft.com/en-us/library/gg709713(v=exchg.80).aspx for available types
//
+ (NSCalendarDate *) dateFromFilterType: (NSString *) theFilterType
{
NSCalendarDate *d;
d = [NSCalendarDate calendarDate];
if (d)
{
int value;
switch ([theFilterType intValue])
{
case 1:
value = ONE_DAY;
break;
case 2:
value = 3 * ONE_DAY;
break;
case 3:
value = 7 * ONE_DAY;
break;
case 4:
value = 14 * ONE_DAY;
break;
case 5:
value = 30 * ONE_DAY;
break;
case 6:
value = 90 * ONE_DAY;
break;
case 7:
value = 180 * ONE_DAY;
break;
case 0:
case 8:
default:
return nil;
}
return [d initWithTimeIntervalSinceNow: -value];
}
return d;
}
@end
+46
View File
@@ -0,0 +1,46 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __NSDATAACTIVESYNC_H__
#define __NSDATAACTIVESYNC_H__
#import <Foundation/NSData.h>
@class NSString;
@class WOContext;
@interface NSData (ActiveSync)
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context;
- (NSData *) wbxml2xml;
- (NSData *) xml2wbxml;
@end
#endif
+152
View File
@@ -0,0 +1,152 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "NSData+ActiveSync.h"
#import <Foundation/NSProcessInfo.h>
#import <Foundation/NSString.h>
#import <NGExtensions/NGBase64Coding.h>
#include <wbxml/wbxml.h>
#include <wbxml/wbxml_conv.h>
#include <wbxml/wbxml_errors.h>
#define WBXMLDEBUG 0
@implementation NSData (ActiveSync)
- (void) _dumpToFile
{
NSString *path;
path = [NSString stringWithFormat: @"/tmp/%@.data", [[NSProcessInfo processInfo] globallyUniqueString]];
[self writeToFile: path atomically: YES];
NSLog(@"Original data written to: %@", path);
}
//
// Encodes the data in base64 and strip newline characters
//
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context
{
return [[self stringByEncodingBase64] stringByReplacingString: @"\n" withString: @""];
}
- (NSData *) wbxml2xml
{
WBXMLGenXMLParams params;
NSData *data;
unsigned int wbxml_len, xml_len, ret;
unsigned char *wbxml, *xml;
wbxml = (unsigned char*)[self bytes];
wbxml_len = [self length];
xml = NULL;
xml_len = 0;
params.lang = WBXML_LANG_ACTIVESYNC;
params.gen_type = WBXML_GEN_XML_INDENT;
params.indent = 1;
params.keep_ignorable_ws = FALSE;
ret = wbxml_conv_wbxml2xml_withlen(wbxml, wbxml_len, &xml, &xml_len, &params);
if (ret != WBXML_OK)
{
NSLog(@"wbxml2xmlFromContent: failed: %s\n", wbxml_errors_string(ret));
[self _dumpToFile];
return nil;
}
data = [[NSData alloc] initWithBytes: xml length: xml_len];
#if WBXMLDEBUG
[data writeToFile: @"/tmp/protocol.decoded" atomically: YES];
#endif
free(xml);
return AUTORELEASE(data);
}
- (NSData *) xml2wbxml
{
WBXMLConvXML2WBXML *conv;
NSData *data;
unsigned int wbxml_len, xml_len, ret;
unsigned char *wbxml, *xml;
xml = (unsigned char*)[self bytes];
xml_len = [self length];
wbxml = NULL;
wbxml_len = 0;
conv = NULL;
ret = wbxml_conv_xml2wbxml_create(&conv);
if (ret != WBXML_OK)
{
NSLog(@"xml2wbxmlFromContent: failed: %s\n", wbxml_errors_string(ret));
[self _dumpToFile];
return nil;
}
wbxml_conv_xml2wbxml_enable_preserve_whitespaces(conv);
// From libwbxml's changelog in v0.11.0: "The public ID is set to unknown and the DTD is not included. This is required for Microsoft ActiveSync."
wbxml_conv_xml2wbxml_disable_public_id(conv);
wbxml_conv_xml2wbxml_disable_string_table(conv);
ret = wbxml_conv_xml2wbxml_run(conv, xml, xml_len, &wbxml, &wbxml_len);
if (ret != WBXML_OK)
{
NSLog(@"xml2wbxmlFromContent: failed: %s\n", wbxml_errors_string(ret));
[self _dumpToFile];
free(wbxml);
wbxml_conv_xml2wbxml_destroy(conv);
return nil;
}
data = [[NSData alloc] initWithBytes: wbxml length: wbxml_len];
#if WBXMLDEBUG
[data writeToFile: @"/tmp/protocol.encoded" atomically: YES];
#endif
free(wbxml);
wbxml_conv_xml2wbxml_destroy(conv);
return AUTORELEASE(data);
}
@end
+45
View File
@@ -0,0 +1,45 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __NSDATEACTIVESYNC_H__
#define __NSDATEACTIVESYNC_H__
#import <Foundation/NSDate.h>
@class NSString;
@class WOContext;
@interface NSDate (ActiveSync)
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context;
- (NSString *) activeSyncRepresentationWithoutSeparatorsInContext: (WOContext *) context;
@end
#endif
+52
View File
@@ -0,0 +1,52 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "NSDate+ActiveSync.h"
#import <Foundation/NSString.h>
#import <Foundation/NSTimeZone.h>
@implementation NSDate (ActiveSync)
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context
{
return [self descriptionWithCalendarFormat: @"%Y-%m-%dT%H:%M:%S.%FZ" timeZone: [NSTimeZone timeZoneWithName: @"GMT"] locale: nil];
}
//
// From [MS-ASDTYPE].pdf - section 2.3 "Dates and times in calendar items MUST NOT include punctuation separators."
//
- (NSString *) activeSyncRepresentationWithoutSeparatorsInContext: (WOContext *) context
{
return [self descriptionWithCalendarFormat: @"%Y%m%dT%H%M%SZ" timeZone: [NSTimeZone timeZoneWithName: @"GMT"] locale: nil];
}
@end
+56
View File
@@ -0,0 +1,56 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __NSSTRINGACTIVESYNC_H__
#define __NSSTRINGACTIVESYNC_H__
#import <Foundation/NSString.h>
#include "SOGoActiveSyncConstants.h"
@class NSCalendarDate;
@class NSData;
@class WOContext;
@interface NSString (ActiveSync)
- (NSString *) sanitizedServerIdWithType: (SOGoMicrosoftActiveSyncFolderType) folderType;
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context;
- (int) activeSyncFolderType;
- (NSString *) realCollectionIdWithFolderType: (SOGoMicrosoftActiveSyncFolderType *) folderType;
- (NSCalendarDate *) calendarDate;
- (NSString *) deviceId;
- (NSString *) deviceType;
- (NSString *) attachmentName;
- (NSString *) command;
- (NSData *) convertHexStringToBytes;
@end
#endif
+388
View File
@@ -0,0 +1,388 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "NSString+ActiveSync.h"
#include <Foundation/NSArray.h>
#include <Foundation/NSCalendarDate.h>
#include <Foundation/NSData.h>
#include <Foundation/NSDate.h>
#include <SOGo/NSString+Utilities.h>
#include <SOGo/NSData+Crypto.h>
#include <NGExtensions/NGBase64Coding.h>
#include <NGExtensions/NSString+misc.h>
static NSArray *easCommandCodes = nil;
static NSArray *easCommandParameters = nil;
@implementation NSString (ActiveSync)
- (NSString *) sanitizedServerIdWithType: (SOGoMicrosoftActiveSyncFolderType) folderType
{
if (folderType == ActiveSyncEventFolder)
{
int len;
len = [self length];
if (len > 4 && [self hasSuffix: @".ics"])
return [self substringToIndex: len-4];
else
return [NSString stringWithFormat: @"%@.ics", self];
}
return self;
}
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context
{
NSString *s;
s = [self safeString];
return [s stringByEscapingHTMLString];
}
- (int) activeSyncFolderType
{
if ([self isEqualToString: @"inbox"])
return 2;
else if ([self isEqualToString: @"draft"])
return 3;
else if ([self isEqualToString: @"sent"])
return 5;
else if ([self isEqualToString: @"trash"])
return 4;
return 12;
}
- (NSString *) realCollectionIdWithFolderType: (SOGoMicrosoftActiveSyncFolderType *) folderType;
{
NSString *realCollectionId, *v;
*folderType = ActiveSyncGenericFolder;
v = [self stringByUnescapingURL];
if ([v hasPrefix: @"vevent/"])
{
realCollectionId = [v substringFromIndex: 7];
*folderType = ActiveSyncEventFolder;
}
else if ([v hasPrefix: @"vtodo/"])
{
realCollectionId = [v substringFromIndex: 6];
*folderType = ActiveSyncTaskFolder;
}
else if ([v hasPrefix: @"vcard/"])
{
realCollectionId = [v substringFromIndex: 6];
*folderType = ActiveSyncContactFolder;
}
else if ([v hasPrefix: @"mail/"])
{
realCollectionId = [[v stringByUnescapingURL] substringFromIndex: 5];
*folderType = ActiveSyncMailFolder;
}
else
{
realCollectionId = nil;
}
return realCollectionId;
}
//
// 2014-01-16T05:00:00.000Z
//
// See http://www.gnustep.org/resources/documentation/Developer/Base/Reference/NSCalendarDate.html#method$NSCalendarDate-initWithString$calendarFormat$ for the format details.
//
- (NSCalendarDate *) calendarDate
{
id o;
o = [NSCalendarDate dateWithString: self calendarFormat: @"%Y%m%dT%H%M%SZ"];
if (!o)
o = [NSCalendarDate dateWithString: self calendarFormat: @"%Y-%m-%dT%H:%M:%S.%FZ"];
return o;
}
- (NSString *) _valueForParameter: (NSString *) theParameter
{
NSMutableArray *components;
NSString *s;
int i;
components = [NSMutableArray arrayWithArray: [[[self componentsSeparatedByString: @"?"] lastObject] componentsSeparatedByString: @"&"]];
// We handle BASE64 encoded queryStrings. See http://msdn.microsoft.com/en-us/library/ee160227%28v=exchg.80%29.aspx for details.
if ([components count] == 1)
{
NSString *deviceType, *parameterValue;
NSData *queryString;
int cmd_code, deviceid_length, policy_length, devicetype_length, parameter_code, parameter_length, i;
const char* qs_bytes;
queryString = [[components objectAtIndex: 0] dataByDecodingBase64];
qs_bytes = (const char*)[queryString bytes];
if (!easCommandCodes)
{
easCommandCodes = [NSArray arrayWithObjects:@"Sync", @"SendMail", @"SmartForward", @"SmartReply", @"GetAttachment", @"na", @"na", @"na", @"na",
@"FolderSync", @"FolderCreate", @"FolderDelete", @"FolderUpdate", @"MoveItems", @"GetItemEstimate", @"MeetingResponse",
@"Search", @"Settings", @"Ping", @"ItemOperations", @"Provision", @"ResolveRecipients", @"ValidateCert", nil];
RETAIN(easCommandCodes);
}
if (!easCommandParameters)
{
easCommandParameters = [NSArray arrayWithObjects:@"AttachmentName", @"CollectionId", @"na", @"ItemId", @"LongId", @"na", @"Occurrence", @"Options", @"User", nil];
RETAIN(easCommandParameters);
}
// Command code, 1 byte, ie.: cmd=
cmd_code = qs_bytes[1];
[components addObject: [NSString stringWithFormat: @"cmd=%@", [easCommandCodes objectAtIndex: cmd_code]]];
// Device ID length and Device ID (variable)
deviceid_length = qs_bytes[4];
[components addObject: [NSString stringWithFormat: @"deviceId=%@", [[NSData encodeDataAsHexString: [queryString subdataWithRange: NSMakeRange(5, deviceid_length)]] uppercaseString]]];
// Device type length and type (variable)
policy_length = qs_bytes[5+deviceid_length];
devicetype_length = qs_bytes[5+deviceid_length+1+policy_length];
deviceType = [[NSString alloc] initWithData: [queryString subdataWithRange: NSMakeRange(5+deviceid_length+1+policy_length+1, devicetype_length)]
encoding: NSASCIIStringEncoding];
AUTORELEASE(deviceType);
[components addObject: [NSString stringWithFormat: @"deviceType=%@", deviceType]];
// Command Parameters
i = 5+deviceid_length+1+policy_length+1+devicetype_length;
while (i < [queryString length])
{
parameter_code = qs_bytes[i];
parameter_length = qs_bytes[i+1];
parameterValue = [[NSString alloc] initWithData: [queryString subdataWithRange: NSMakeRange(i+1+1, parameter_length)]
encoding: NSASCIIStringEncoding];
AUTORELEASE(parameterValue);
// parameter_code 7 == Options
// http://msdn.microsoft.com/en-us/library/ee237789(v=exchg.80).aspx
if (parameter_code == 7)
[components addObject: [NSString stringWithFormat: @"%@=%@", [easCommandParameters objectAtIndex: parameter_code],
([parameterValue isEqualToString: @"\001"]) ? @"SaveInSent" : @"AcceptMultiPart"]];
else
[components addObject: [NSString stringWithFormat: @"%@=%@", [easCommandParameters objectAtIndex: parameter_code], parameterValue]];
i = i + 1 + 1 + parameter_length;
}
}
for (i = 0; i < [components count]; i++)
{
s = [components objectAtIndex: i];
if ([[s uppercaseString] hasPrefix: theParameter])
return [s substringFromIndex: [theParameter length]];
}
return nil;
}
//
// This method extracts the "DeviceId" from a URI:
//
// /SOGo/Microsoft-Server-ActiveSync?Cmd=FolderSync&User=sogo10&DeviceId=SEC17CD1A3E9E3F2&DeviceType=SAMSUNGSGHI317M
//
- (NSString *) deviceId
{
NSString *s;
s = [self _valueForParameter: @"DEVICEID="];
if (!s)
s = @"Unknown";
return s;
}
//
// This method extracts the "DeviceType" from a URI:
//
// /SOGo/Microsoft-Server-ActiveSync?Cmd=FolderSync&User=sogo10&DeviceId=SEC17CD1A3E9E3F2&DeviceType=SAMSUNGSGHI317M
//
- (NSString *) deviceType
{
NSString *s;
s = [self _valueForParameter: @"DEVICETYPE="];
if (!s)
s = @"Unknown";
return s;
}
// This method extracts the "AttachmentName" from a URI:
//
// /SOGo/Microsoft-Server-ActiveSync?Cmd=GetAttachment&User=sogo&DeviceId=HTCa04b4932597acd3f2dc1a918b9728&DeviceType=htcvision&AttachmentName=mail/TestFldr/8/2
//
- (NSString *) attachmentName
{
NSString *s;
s = [self _valueForParameter: @"ATTACHMENTNAME="];
if (!s)
s = @"Unknown";
return s;
}
//
//
//
- (NSString *) command
{
NSString *s;
s = [self _valueForParameter: @"CMD="];
if (!s)
s = @"Unknown";
return s;
}
//
// FIXME: combine with our OpenChange code.
//
- (char) _decodeHexByte: (char) byteChar
{
char newByte;
if (byteChar >= 48 && byteChar <= 57)
newByte = (uint8_t) byteChar - 48;
else if (byteChar >= 65 && byteChar <= 70)
newByte = (uint8_t) byteChar - 55;
else if (byteChar >= 97 && byteChar <= 102)
newByte = (uint8_t) byteChar - 87;
else
newByte = -1;
return newByte;
}
//
// FIXME: combine with our OpenChange code.
//
- (BOOL) _decodeHexByte: (uint8_t *) byte
atPos: (NSUInteger) pos
{
BOOL error = NO;
char newByte;
unichar byteChar;
byteChar = [self characterAtIndex: pos];
if (byteChar < 256)
{
newByte = [self _decodeHexByte: (char) byteChar];
if (newByte == -1)
error = YES;
else
*byte = newByte;
}
else
error = YES;
return error;
}
//
// FIXME: combine with our OpenChange code.
//
- (BOOL) _decodeHexPair: (uint8_t *) byte
atPos: (NSUInteger) pos
{
BOOL error;
uint8_t lowValue, highValue;
error = [self _decodeHexByte: &highValue atPos: pos];
if (!error)
{
error = [self _decodeHexByte: &lowValue atPos: pos + 1];
if (!error)
*byte = highValue << 4 | lowValue;
}
return error;
}
//
// FIXME: combine with our OpenChange code.
//
- (NSData *) convertHexStringToBytes
{
NSUInteger count, strLen, bytesLen;
uint8_t *bytes, *currentByte;
NSData *decoded = nil;
BOOL error = NO;
strLen = [self length];
if ((strLen % 2) == 0)
{
bytesLen = strLen / 2;
bytes = NSZoneCalloc (NULL, bytesLen, sizeof (uint8_t));
currentByte = bytes;
for (count = 0; !error && count < strLen; count += 2)
{
error = [self _decodeHexPair: currentByte atPos: count];
currentByte++;
}
if (error)
NSZoneFree (NULL, bytes);
else
decoded = [NSData dataWithBytesNoCopy: bytes
length: bytesLen
freeWhenDone: YES];
}
return decoded;
}
@end
+12
View File
@@ -0,0 +1,12 @@
In order to use this software in production environments, you need to
get a proper usage license from Microsoft. Please contact them directly
to negotiate the fees associated to your user base.
To contact Microsoft, please visit:
http://www.microsoft.com/en-us/legal/intellectualproperty/IPLicensing/Programs/exchangeactivesyncprotocol.aspx
and send an email to iplicreq@microsoft.com
Inverse inc. provides this software for free, but is not responsible
for anything related to its usage.
+42
View File
@@ -0,0 +1,42 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __SOGOACTIVESYNCCONSTANTS_H__
#define __SOGOACTIVESYNCCONSTANTS_H__
typedef enum
{
ActiveSyncGenericFolder = 0,
ActiveSyncMailFolder = 1,
ActiveSyncContactFolder = 2,
ActiveSyncEventFolder = 3,
ActiveSyncTaskFolder = 4,
} SOGoMicrosoftActiveSyncFolderType;
#endif
@@ -0,0 +1,47 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __SOGOACTIVESYNCDISPATCHERSYNC_H__
#define __SOGOACTIVESYNCDISPATCHERSYNC_H__
#import "SOGoActiveSyncDispatcher.h"
#import <DOM/DOMElement.h>
#import <DOM/DOMProtocols.h>
@class WOResponse;
@interface SOGoActiveSyncDispatcher (Sync)
- (void) processSync: (id <DOMElement>) theDocumentElement
inResponse: (WOResponse *) theResponse;
@end
#endif // SOGOACTIVESYNCDISPATCHERSYNC
File diff suppressed because it is too large. Load diff
+56
View File
@@ -0,0 +1,56 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <Foundation/NSObject.h>
#include "SOGoActiveSyncConstants.h"
@class NSException;
@class NSURL;
@interface SOGoActiveSyncDispatcher : NSObject
{
NSURL *folderTableURL;
id context;
}
- (id) collectionFromId: (NSString *) theCollectionId
type: (SOGoMicrosoftActiveSyncFolderType) theFolderType;
- (id) globallyUniqueIDToIMAPFolderName: (NSString *) theIdToTranslate
type: (SOGoMicrosoftActiveSyncFolderType) theFolderType;
- (NSException *) dispatchRequest: (id) theRequest
inResponse: (id) theResponse
context: (id) theContext;
- (NSURL *) folderTableURL;
- (void) ensureFolderTableExists;
@end
File diff suppressed because it is too large. Load diff
+48
View File
@@ -0,0 +1,48 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __SOGOMAILOBJECTACTIVESYNC_H__
#define __SOGOMAILOBJECTACTIVESYNC_H__
#import <Mailer/SOGoMailObject.h>
@class iCalCalendar;
@class NSDictionary;
@class WOContext;
@interface SOGoMailObject (ActiveSync)
- (iCalCalendar *) calendarFromIMIPMessage;
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context;
- (void) takeActiveSyncValues: (NSDictionary *) theValues
inContext: (WOContext *) context;
@end
#endif
+850
View File
@@ -0,0 +1,850 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "SOGoMailObject+ActiveSync.h"
#import <Foundation/NSArray.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSException.h>
#import <Foundation/NSString.h>
#import <NGCards/iCalCalendar.h>
#import <NGCards/iCalDateTime.h>
#import <NGCards/iCalEvent.h>
#import <NGCards/iCalPerson.h>
#import <NGCards/iCalTimeZone.h>
#import <NGExtensions/NGBase64Coding.h>
#import <NGExtensions/NGQuotedPrintableCoding.h>
#import <NGExtensions/NSString+misc.h>
#import <NGExtensions/NSString+Encoding.h>
#import <NGImap4/NGImap4Envelope.h>
#import <NGImap4/NGImap4EnvelopeAddress.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGMime/NGMimeBodyPart.h>
#import <NGMime/NGMimeFileData.h>
#import <NGMime/NGMimeMultipartBody.h>
#import <NGMime/NGMimeType.h>
#import <NGMail/NGMimeMessageParser.h>
#import <NGMail/NGMimeMessage.h>
#import <NGMail/NGMimeMessageGenerator.h>
#include "iCalTimeZone+ActiveSync.h"
#include "NSData+ActiveSync.h"
#include "NSDate+ActiveSync.h"
#include "NSString+ActiveSync.h"
#include <Appointments/iCalEntityObject+SOGo.h>
#include <Appointments/iCalPerson+SOGo.h>
#include <Mailer/NSString+Mail.h>
#include <Mailer/SOGoMailBodyPart.h>
#include <SOGo/SOGoUser.h>
#include <SOGo/NSString+Utilities.h>
typedef struct {
uint32_t dwLowDateTime;
uint32_t dwHighDateTime;
} FILETIME;
struct GlobalObjectId {
uint8_t ByteArrayID[16];
uint8_t YH;
uint8_t YL;
uint8_t Month;
uint8_t D;
FILETIME CreationTime;
uint8_t X[8];
uint32_t Size;
uint8_t* Data;
};
@implementation SOGoMailObject (ActiveSync)
//
//
//
- (void) _setInstanceDate: (struct GlobalObjectId *) newGlobalId
fromDate: (NSCalendarDate *) instanceDate
{
uint16_t year;
if (instanceDate)
{
//[instanceDate setTimeZone: timeZone];
year = [instanceDate yearOfCommonEra];
newGlobalId->YH = year >> 8;
newGlobalId->YL = year & 0xff;
newGlobalId->Month = [instanceDate monthOfYear];
newGlobalId->D = [instanceDate dayOfMonth];
}
}
//
// The GlobalObjId is documented here: http://msdn.microsoft.com/en-us/library/ee160198(v=EXCHG.80).aspx
//
- (NSData *) _computeGlobalObjectIdFromEvent: (iCalEvent *) event
{
NSData *binPrefix, *globalObjectId, *uidAsASCII;
NSString *prefix, *uid;
struct GlobalObjectId newGlobalId;
const char *bytes;
prefix = @"040000008200e00074c5b7101a82e008";
// dataPrefix is "vCal-Uid %x01 %x00 %x00 %x00"
uint8_t dataPrefix[] = { 0x76, 0x43, 0x61, 0x6c, 0x2d, 0x55, 0x69, 0x64, 0x01, 0x00, 0x00, 0x00 };
uid = [event uid];
binPrefix = [prefix convertHexStringToBytes];
[binPrefix getBytes: &newGlobalId.ByteArrayID];
[self _setInstanceDate: &newGlobalId
fromDate: [event recurrenceId]];
uidAsASCII = [uid dataUsingEncoding: NSASCIIStringEncoding];
bytes = [uidAsASCII bytes];
// 0x0c is the size of our dataPrefix
newGlobalId.Size = 0x0c + [uidAsASCII length];
newGlobalId.Data = malloc(newGlobalId.Size * sizeof(uint8_t));
memcpy(newGlobalId.Data, dataPrefix, 0x0c);
memcpy(newGlobalId.Data + 0x0c, bytes, newGlobalId.Size - 0x0c);
globalObjectId = [[NSData alloc] initWithBytes: &newGlobalId length: 40 + newGlobalId.Size*sizeof(uint8_t)];
free(newGlobalId.Data);
return [globalObjectId autorelease];
}
//
// For debugging purposes...
//
- (NSString *) _uidFromGlobalObjectId: (NSData *) objectId
{
NSString *uid;
struct GlobalObjectId *newGlobalId;
NSUInteger length;
uint8_t *bytes;
length = [objectId length];
uid = nil;
bytes = malloc(length*sizeof(uint8_t));
[objectId getBytes: bytes length: length];
newGlobalId = (struct GlobalObjectId *)bytes;
// We must take the offset (dataPrefix) into account
uid = [[NSString alloc] initWithBytes: newGlobalId->Data+12 length: newGlobalId->Size-12 encoding: NSASCIIStringEncoding];
free(bytes);
return AUTORELEASE(uid);
}
//
//
//
- (NSString *) _emailAddressesFrom: (NSArray *) enveloppeAddresses
{
NGImap4EnvelopeAddress *address;
NSString *email, *rc, *name;
NSMutableArray *addresses;
int i, max;
rc = nil;
max = [enveloppeAddresses count];
if (max > 0)
{
addresses = [NSMutableArray array];
for (i = 0; i < max; i++)
{
address = [enveloppeAddresses objectAtIndex: i];
name = [address personalName];
email = [NSString stringWithFormat: @"\"%@\" <%@>", (name ? name : [address baseEMail]), [address baseEMail]];
if (email)
[addresses addObject: email];
}
rc = [addresses componentsJoinedByString: @", "];
}
return rc;
}
//
//
//
- (NSData *) _preferredBodyDataInMultipartUsingType: (int) theType
{
NSString *encoding, *key, *plainKey, *htmlKey, *type, *subtype;
NSDictionary *textParts, *part;
NSEnumerator *e;
NSData *d;
textParts = [self fetchPlainTextParts];
e = [textParts keyEnumerator];
plainKey = nil;
htmlKey = nil;
d = nil;
while ((key = [e nextObject]))
{
part = [self lookupInfoForBodyPart: key];
type = [part valueForKey: @"type"];
subtype = [part valueForKey: @"subtype"];
if ([type isEqualToString: @"text"] && [subtype isEqualToString: @"html"])
htmlKey = key;
else if ([type isEqualToString: @"text"] && [subtype isEqualToString: @"plain"])
plainKey = key;
}
key = nil;
if (theType == 2)
key = htmlKey;
else if (theType == 1)
key = plainKey;
if (key)
{
NSString *s, *charset;
d = [[self fetchPlainTextParts] objectForKey: key];
encoding = [[self lookupInfoForBodyPart: key] objectForKey: @"encoding"];
if ([encoding caseInsensitiveCompare: @"base64"] == NSOrderedSame)
d = [d dataByDecodingBase64];
else if ([encoding caseInsensitiveCompare: @"quoted-printable"] == NSOrderedSame)
d = [d dataByDecodingQuotedPrintableTransferEncoding];
charset = [[[self lookupInfoForBodyPart: key] objectForKey: @"parameterList"] objectForKey: @"charset"];
if (![charset length])
charset = @"us-ascii";
s = [NSString stringWithData: d usingEncodingNamed: charset];
d = [s dataUsingEncoding: NSUTF8StringEncoding];
}
return d;
}
//
//
//
- (void) _sanitizedMIMEPart: (id) thePart
performed: (BOOL *) b
{
if ([thePart isKindOfClass: [NGMimeMultipartBody class]])
{
NGMimeBodyPart *part;
NSArray *parts;
int i;
parts = [thePart parts];
for (i = 0; i < [parts count]; i++)
{
part = [parts objectAtIndex: i];
[self _sanitizedMIMEPart: part
performed: b];
}
}
else if ([thePart isKindOfClass: [NGMimeBodyPart class]])
{
NGMimeFileData *fdata;
id body;
body = [thePart body];
if ([body isKindOfClass: [NGMimeMultipartBody class]])
{
[self _sanitizedMIMEPart: body
performed: b];
}
else if (([body isKindOfClass: [NSData class]] || [body isKindOfClass: [NSString class]]) &&
[[[thePart contentType] type] isEqualToString: @"text"] &&
([[[thePart contentType] subType] isEqualToString: @"plain"] || [[[thePart contentType] subType] isEqualToString: @"html"]))
{
// We make sure everything is encoded in UTF-8
NGMimeType *mimeType;
NSString *s;
if ([body isKindOfClass: [NSData class]])
{
NSString *charset;
charset = [[thePart contentType] valueOfParameter: @"charset"];
if (![charset length])
charset = @"us-ascii";
s = [NSString stringWithData: body usingEncodingNamed: charset];
}
else
{
// Handle situations when SOPE stupidly returns us a NSString
// This can happen for Content-Type: text/plain, Content-Transfer-Encoding: 8bit
s = body;
}
if (s)
{
// We sanitize the content immediately, in case we have non-UNICODE safe
// characters that would be re-encoded later in HTML entities and thus,
// ignore afterwards.
s = [s safeString];
body = [s dataUsingEncoding: NSUTF8StringEncoding];
}
mimeType = [NGMimeType mimeType: [[thePart contentType] type]
subType: [[thePart contentType] subType]
parameters: [NSDictionary dictionaryWithObject: @"utf-8" forKey: @"charset"]];
[thePart setHeader: mimeType forKey: @"content-type"];
fdata = [[NGMimeFileData alloc] initWithBytes: [body bytes]
length: [body length]];
[thePart setBody: fdata];
RELEASE(fdata);
*b = YES;
}
}
}
//
//
//
- (NSData *) _sanitizedMIMEMessage
{
NGMimeMessageParser *parser;
NGMimeMessage *message;
NSData *d;
BOOL b;
d = [self content];
parser = [[NGMimeMessageParser alloc] init];
AUTORELEASE(parser);
message = [parser parsePartFromData: d];
b = NO;
if (message)
{
[self _sanitizedMIMEPart: [message body]
performed: &b];
if (b)
{
NGMimeMessageGenerator *generator;
generator = [[NGMimeMessageGenerator alloc] init];
AUTORELEASE(generator);
d = [generator generateMimeFromPart: message];
}
}
return d;
}
//
//
//
- (NSData *) _preferredBodyDataUsingType: (int) theType
nativeType: (int *) theNativeType
{
NSString *type, *subtype, *encoding;
NSData *d;
type = [[[self bodyStructure] valueForKey: @"type"] lowercaseString];
subtype = [[[self bodyStructure] valueForKey: @"subtype"] lowercaseString];
d = nil;
// We determine the native type
if ([type isEqualToString: @"text"] && [subtype isEqualToString: @"plain"])
*theNativeType = 1;
else if ([type isEqualToString: @"text"] && [subtype isEqualToString: @"html"])
*theNativeType = 2;
else if ([type isEqualToString: @"multipart"])
*theNativeType = 4;
// We get the right part based on the preference
if (theType == 1 || theType == 2)
{
if ([type isEqualToString: @"text"])
{
NSString *s, *charset;
charset = [[[self lookupInfoForBodyPart: @""] objectForKey: @"parameterList"] objectForKey: @"charset"];
if (![charset length])
charset = @"us-ascii";
d = [[self fetchPlainTextParts] objectForKey: @""];
// We check if we have base64 encoded parts. If so, we just
// un-encode them before using them
encoding = [[self lookupInfoForBodyPart: @""] objectForKey: @"encoding"];
if ([encoding caseInsensitiveCompare: @"base64"] == NSOrderedSame)
d = [d dataByDecodingBase64];
else if ([encoding caseInsensitiveCompare: @"quoted-printable"] == NSOrderedSame)
d = [d dataByDecodingQuotedPrintableTransferEncoding];
s = [NSString stringWithData: d usingEncodingNamed: charset];
// Check if we must convert html->plain
if (theType == 1 && [subtype isEqualToString: @"html"])
{
s = [s htmlToText];
}
d = [s dataUsingEncoding: NSUTF8StringEncoding];
}
else if ([type isEqualToString: @"multipart"])
{
d = [self _preferredBodyDataInMultipartUsingType: theType];
}
}
else if (theType == 4)
{
// We sanitize the content *ONLY* for Outlook clients. Outlook has strange issues
// with quoted-printable/base64 encoded text parts. It just doesn't decode them.
if ([[context objectForKey: @"DeviceType"] isEqualToString: @"WindowsOutlook15"])
d = [self _sanitizedMIMEMessage];
else
d = [self content];
}
return d;
}
//
//
//
- (iCalCalendar *) calendarFromIMIPMessage
{
NSDictionary *part;
NSArray *parts;
int i;
// We check if we have at least 2 parts and if one of them is a text/calendar
parts = [[self bodyStructure] objectForKey: @"parts"];
if ([parts count] > 1)
{
for (i = 0; i < [parts count]; i++)
{
part = [parts objectAtIndex: i];
if ([[part objectForKey: @"type"] isEqualToString: @"text"] &&
[[part objectForKey: @"subtype"] isEqualToString: @"calendar"])
{
id bodyPart;
bodyPart = [self lookupImap4BodyPartKey: [NSString stringWithFormat: @"%d", i+1]
inContext: self->context];
if (bodyPart)
{
iCalCalendar *calendar;
NSData *calendarData;
calendarData = [bodyPart fetchBLOB];
calendar = nil;
NS_DURING
calendar = [iCalCalendar parseSingleFromSource: calendarData];
NS_HANDLER
calendar = nil;
NS_ENDHANDLER
return calendar;
}
}
}
}
return nil;
}
//
//
//
- (NSString *) activeSyncRepresentationInContext: (WOContext *) _context
{
NSAutoreleasePool *pool;
NSData *d, *globalObjId;
NSArray *attachmentKeys;
NSMutableString *s;
id value;
iCalCalendar *calendar;
int preferredBodyType, nativeBodyType;
s = [NSMutableString string];
// To - "The value of this element contains one or more e-mail addresses.
// If there are multiple e-mail addresses, they are separated by commas."
value = [self _emailAddressesFrom: [[self envelope] to]];
if (value)
[s appendFormat: @"<To xmlns=\"Email:\">%@</To>", [value activeSyncRepresentationInContext: context]];
// From
value = [self _emailAddressesFrom: [[self envelope] from]];
if (value)
[s appendFormat: @"<From xmlns=\"Email:\">%@</From>", [value activeSyncRepresentationInContext: context]];
// Subject
value = [self decodedSubject];
if (value)
{
[s appendFormat: @"<Subject xmlns=\"Email:\">%@</Subject>", [value activeSyncRepresentationInContext: context]];
[s appendFormat: @"<ThreadTopic xmlns=\"Email:\">%@</ThreadTopic>", [value activeSyncRepresentationInContext: context]];
}
// DateReceived
value = [self date];
if (value)
[s appendFormat: @"<DateReceived xmlns=\"Email:\">%@</DateReceived>", [value activeSyncRepresentationInContext: context]];
// DisplayTo
[s appendFormat: @"<DisplayTo xmlns=\"Email:\">%@</DisplayTo>", [[context activeUser] login]];
// Cc - same syntax as the To field
value = [self _emailAddressesFrom: [[self envelope] cc]];
if (value)
[s appendFormat: @"<Cc xmlns=\"Email:\">%@</Cc>", [value activeSyncRepresentationInContext: context]];
// Importance - FIXME
[s appendFormat: @"<Importance xmlns=\"Email:\">%@</Importance>", @"1"];
// Read
[s appendFormat: @"<Read xmlns=\"Email:\">%d</Read>", ([self read] ? 1 : 0)];
// We handle MeetingRequest
calendar = [self calendarFromIMIPMessage];
if (calendar)
{
NSString *method, *className;
iCalPerson *attendee;
iCalTimeZone *tz;
iCalEvent *event;
iCalPersonPartStat partstat;
int v;
event = [[calendar events] lastObject];
method = [[event parent] method];
// If we are the organizer, let's pick the attendee based on the From address
if ([event userIsOrganizer: [context activeUser]])
attendee = [event findAttendeeWithEmail: [[[[self envelope] from] lastObject] baseEMail]];
else
attendee = [event findAttendeeWithEmail: [[[context activeUser] allEmails] objectAtIndex: 0]];
partstat = [attendee participationStatus];
// We generate the correct MessageClass
if ([method isEqualToString: @"REQUEST"])
className = @"IPM.Schedule.Meeting.Request";
else if ([method isEqualToString: @"REPLY"])
{
switch (partstat)
{
case iCalPersonPartStatAccepted:
className = @"IPM.Schedule.Meeting.Resp.Pos";
break;
case iCalPersonPartStatDeclined:
className = @"IPM.Schedule.Meeting.Resp.Neg";
break;
case iCalPersonPartStatTentative:
case iCalPersonPartStatNeedsAction:
className = @"IPM.Schedule.Meeting.Resp.Tent";
break;
default:
className = @"IPM.Appointment";
NSLog(@"unhandled part stat");
}
}
else if ([method isEqualToString: @"COUNTER"])
className = @"IPM.Schedule.Meeting.Resp.Tent";
else if ([method isEqualToString: @"CANCEL"])
className = @"IPM.Schedule.Meeting.Cancelled";
else
className = @"IPM.Appointment";
[s appendFormat: @"<MessageClass xmlns=\"Email:\">%@</MessageClass>", className];
[s appendString: @"<MeetingRequest xmlns=\"Email:\">"];
[s appendFormat: @"<AllDayEvent xmlns=\"Email:\">%d</AllDayEvent>", ([event isAllDay] ? 1 : 0)];
// StartTime -- http://msdn.microsoft.com/en-us/library/ee157132(v=exchg.80).aspx
if ([event startDate])
[s appendFormat: @"<StartTime xmlns=\"Email:\">%@</StartTime>", [[event startDate] activeSyncRepresentationWithoutSeparatorsInContext: context]];
if ([event timeStampAsDate])
[s appendFormat: @"<DTStamp xmlns=\"Email:\">%@</DTStamp>", [[event timeStampAsDate] activeSyncRepresentationWithoutSeparatorsInContext: context]];
else if ([event created])
[s appendFormat: @"<DTStamp xmlns=\"Email:\">%@</DTStamp>", [[event created] activeSyncRepresentationWithoutSeparatorsInContext: context]];
// EndTime -- http://msdn.microsoft.com/en-us/library/ee157945(v=exchg.80).aspx
if ([event endDate])
[s appendFormat: @"<EndTime xmlns=\"Email:\">%@</EndTime>", [[event endDate] activeSyncRepresentationWithoutSeparatorsInContext: context]];
// FIXME: Single appointment - others are not supported right now
[s appendFormat: @"<InstanceType xmlns=\"Email:\">%d</InstanceType>", 0];
// Location
if ([[event location] length])
[s appendFormat: @"<Location xmlns=\"Email:\">%@</Location>", [[event location] activeSyncRepresentationInContext: context]];
[s appendFormat: @"<Organizer xmlns=\"Email:\">%@</Organizer>", [[[event organizer] mailAddress] activeSyncRepresentationInContext: context]];
// This will trigger the SendMail command. We set it to no for email invitations as
// SOGo will send emails when MeetingResponse is called.
[s appendFormat: @"<ResponseRequested xmlns=\"Email:\">%d</ResponseRequested>", 0];
// Sensitivity
if ([[event accessClass] isEqualToString: @"PRIVATE"])
v = 2;
if ([[event accessClass] isEqualToString: @"CONFIDENTIAL"])
v = 3;
else
v = 0;
[s appendFormat: @"<Sensitivity xmlns=\"Email:\">%d</Sensitivity>", v];
[s appendFormat: @"<BusyStatus xmlns=\"Email:\">%d</BusyStatus>", 2];
// Timezone
tz = [(iCalDateTime *)[event firstChildWithTag: @"dtstart"] timeZone];
if (!tz)
tz = [iCalTimeZone timeZoneForName: @"Europe/London"];
[s appendFormat: @"<TimeZone xmlns=\"Email:\">%@</TimeZone>", [tz activeSyncRepresentationInContext: context]];
// We disallow new time proposals
[s appendFormat: @"<DisallowNewTimeProposal xmlns=\"Email:\">%d</DisallowNewTimeProposal>", 1];
// From http://blogs.msdn.com/b/exchangedev/archive/2011/07/22/working-with-meeting-requests-in-exchange-activesync.aspx:
//
// "Clients that need to determine whether the GlobalObjId element for a meeting request corresponds to an existing Calendar
// object in the Calendar folder have to convert the GlobalObjId element value to a UID element value to make the comparison."
//
globalObjId = [self _computeGlobalObjectIdFromEvent: event];
[s appendFormat: @"<GlobalObjId xmlns=\"Email:\">%@</GlobalObjId>", [globalObjId activeSyncRepresentationInContext: context]];
// We set the right message type - we must set AS version to 14.1 for this
[s appendFormat: @"<MeetingMessageType xmlns=\"Email2:\">%d</MeetingMessageType>", 1];
[s appendString: @"</MeetingRequest>"];
// ContentClass
[s appendFormat: @"<ContentClass xmlns=\"Email:\">%@</ContentClass>", @"urn:content-classes:calendarmessage"];
}
else
{
// MesssageClass and ContentClass
[s appendFormat: @"<MessageClass xmlns=\"Email:\">%@</MessageClass>", @"IPM.Note"];
[s appendFormat: @"<ContentClass xmlns=\"Email:\">%@</ContentClass>", @"urn:content-classes:message"];
}
// Reply-To - FIXME
//NSArray *replyTo = [[message objectForKey: @"envelope"] replyTo];
//if ([replyTo count])
// [s appendFormat: @"<Reply-To xmlns=\"Email:\">%@</Reply-To>", [addressFormatter stringForArray: replyTo]];
// InternetCPID - 65001 == UTF-8, we use this all the time for now.
// - 20127 == US-ASCII
[s appendFormat: @"<InternetCPID xmlns=\"Email:\">%@</InternetCPID>", @"65001"];
// Body - namespace 17
preferredBodyType = [[context objectForKey: @"BodyPreferenceType"] intValue];
// Make use of a local pool here as _preferredBodyDataUsingType:nativeType: will consume
// a significant amout of RAM and file descriptors
pool = [[NSAutoreleasePool alloc] init];
nativeBodyType = 1;
d = [self _preferredBodyDataUsingType: preferredBodyType nativeType: &nativeBodyType];
if (d)
{
NSString *content;
int len, truncated;
content = [[NSString alloc] initWithData: d encoding: NSUTF8StringEncoding];
// FIXME: This is a hack. We should normally avoid doing this as we might get
// broken encodings. We should rather tell that the data was truncated and expect
// a ItemOperations call to download the whole base64 encoding multipart.
//
// See http://social.msdn.microsoft.com/Forums/en-US/b9944e49-9bc9-4ab8-ba33-a9fc08557c5b/mime-raw-data-in-eas-sync-response?forum=os_exchangeprotocols
// for an "interesting" discussion around this.
//
if (!content)
content = [[NSString alloc] initWithData: d encoding: NSISOLatin1StringEncoding];
AUTORELEASE(content);
content = [content activeSyncRepresentationInContext: context];
truncated = 0;
len = [content length];
[s appendString: @"<Body xmlns=\"AirSyncBase:\">"];
[s appendFormat: @"<Type>%d</Type>", preferredBodyType];
[s appendFormat: @"<Truncated>%d</Truncated>", truncated];
[s appendFormat: @"<Preview></Preview>"];
if (!truncated)
{
[s appendFormat: @"<Data>%@</Data>", content];
[s appendFormat: @"<EstimatedDataSize>%d</EstimatedDataSize>", len];
}
[s appendString: @"</Body>"];
}
DESTROY(pool);
// Attachments -namespace 16
attachmentKeys = [self fetchFileAttachmentKeys];
if ([attachmentKeys count])
{
int i;
[s appendString: @"<Attachments xmlns=\"AirSyncBase:\">"];
for (i = 0; i < [attachmentKeys count]; i++)
{
value = [attachmentKeys objectAtIndex: i];
[s appendString: @"<Attachment>"];
[s appendFormat: @"<DisplayName>%@</DisplayName>", [[value objectForKey: @"filename"] activeSyncRepresentationInContext: context]];
// FileReference must be a unique identifier across the whole store. We use the following structure:
// mail/<foldername>/<message UID/<pathofpart>
// mail/INBOX/2
[s appendFormat: @"<FileReference>mail/%@/%@/%@</FileReference>", [[[self container] relativeImap4Name] stringByEscapingURL], [self nameInContainer], [value objectForKey: @"path"]];
[s appendFormat: @"<Method>%d</Method>", 1]; // See: http://msdn.microsoft.com/en-us/library/ee160322(v=exchg.80).aspx
[s appendFormat: @"<EstimatedDataSize>%d</EstimatedDataSize>", [[value objectForKey: @"size"] intValue]];
//[s appendFormat: @"<IsInline>%d</IsInline>", 1];
[s appendString: @"</Attachment>"];
}
[s appendString: @"</Attachments>"];
}
// Flags
[s appendString: @"<Flag xmlns=\"Email:\">"];
[s appendFormat: @"<FlagStatus>%d</FlagStatus>", ([self flagged] ? 2 : 0)];
[s appendString: @"</Flag>"];
// FIXME - support these in the future
//[s appendString: @"<ConversationId xmlns=\"Email2:\">foobar</ConversationId>"];
//[s appendString: @"<ConversationIndex xmlns=\"Email2:\">zot=</ConversationIndex>"];
// NativeBodyType -- http://msdn.microsoft.com/en-us/library/ee218276(v=exchg.80).aspx
// This is a required child element.
// 1 -> plain/text, 2 -> HTML and 3 -> RTF
if (nativeBodyType == 4)
nativeBodyType = 1;
[s appendFormat: @"<NativeBodyType xmlns=\"AirSyncBase:\">%d</NativeBodyType>", nativeBodyType];
return s;
}
//
//
//
// Exemple for a message being marked as read:
//
// <Change>
// <ServerId>607</ServerId>
// <ApplicationData>
// <Read xmlns="Email:">1</Read>
// </ApplicationData>
// </Change>
// </Commands>
//
- (void) takeActiveSyncValues: (NSDictionary *) theValues
inContext: (WOContext *) _context
{
id o;
if ((o = [theValues objectForKey: @"Flag"]))
{
// We must handle empty flags -> {Flag = ""; } - some ActiveSync clients, like the HTC Desire
// will send an empty Flag message when "unflagging" a mail.
if (([o isKindOfClass: [NSMutableDictionary class]]))
{
if ((o = [o objectForKey: @"FlagStatus"]))
{
// 0 = The flag is cleared.
// 1 = The status is set to complete.
// 2 = The status is set to active.
if (([o isEqualToString: @"2"]))
[self addFlags: @"\\Flagged"];
else
[self removeFlags: @"\\Flagged"];
}
}
else
[self removeFlags: @"\\Flagged"];
}
if ((o = [theValues objectForKey: @"Read"]))
{
if ([o intValue])
[self addFlags: @"seen"];
else
[self removeFlags: @"seen"];;
}
}
@end
+55
View File
@@ -0,0 +1,55 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __SOGOSYNCCACHEOBJECT_H__
#define __SOGOSYNCCACHEOBJECT_H__
#import <Foundation/NSObject.h>
@class NSNull;
@interface SOGoSyncCacheObject : NSObject
{
id _uid;
id _sequence;
}
+ (id) syncCacheObjectWithUID: (id) theUID sequence: (id) theSequence;
- (id) uid;
- (void) setUID: (id) theUID;
- (id) sequence;
- (void) setSequence: (id) theSequence;
- (NSComparisonResult) compareUID: (SOGoSyncCacheObject *) theSyncCacheObject;
- (NSComparisonResult) compareSequence: (SOGoSyncCacheObject *) theSyncCacheObject;
@end
#endif
+122
View File
@@ -0,0 +1,122 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "SOGoSyncCacheObject.h"
#import <Foundation/NSNull.h>
#import <Foundation/NSString.h>
@implementation SOGoSyncCacheObject
- (id) init
{
if ((self = [super init]))
{
_uid = nil;
_sequence = nil;
}
return self;
}
+ (id) syncCacheObjectWithUID: (id) theUID sequence: (id) theSequence;
{
id o;
o = [[self alloc] init];
[o setUID: theUID];
[o setSequence: theSequence];
return o;
}
- (void) dealloc
{
RELEASE(_uid);
RELEASE(_sequence);
[super dealloc];
}
- (id) uid
{
return _uid;
}
- (void) setUID: (id) theUID
{
ASSIGN(_uid, theUID);
}
- (id) sequence
{
return _sequence;
}
- (void) setSequence: (id) theSequence
{
ASSIGN(_sequence, theSequence);
}
- (NSComparisonResult) compareUID: (SOGoSyncCacheObject *) theSyncCacheObject
{
return [[self uid] compare: [theSyncCacheObject uid]];
}
//
// We might get NSNull values here, so if both are NSNull instances,
// we sort by UID. If both sequences are equal, we also sort by UID.
//
- (NSComparisonResult) compareSequence: (SOGoSyncCacheObject *) theSyncCacheObject
{
if ([[self sequence] isEqual: [NSNull null]] &&
[[theSyncCacheObject sequence] isEqual: [NSNull null]])
return [self compareUID: theSyncCacheObject];
if (![[self sequence] isEqual: [NSNull null]] && [[theSyncCacheObject sequence] isEqual: [NSNull null]])
return NSOrderedDescending;
if ([[self sequence] isEqual: [NSNull null]] && ![[theSyncCacheObject sequence] isEqual: [NSNull null]])
return NSOrderedAscending;
// Must check this here, to avoid comparing NSNull objects
if ([[self sequence] compare: [theSyncCacheObject sequence]] == NSOrderedSame)
return [self compareUID: theSyncCacheObject];
return [[self sequence] compare: [theSyncCacheObject sequence]];
}
- (NSString *) description
{
return [NSString stringWithFormat: @"%@-%@", _uid, _sequence];
}
@end
@@ -0,0 +1,101 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <NGObjWeb/SoObjectWebDAVDispatcher.h>
#include <NGObjWeb/SoObject+SoDAV.h>
#include <NGObjWeb/WEClientCapabilities.h>
#include <NGObjWeb/WOContext.h>
#include <NGObjWeb/WORequest.h>
#include <NGObjWeb/WOResponse.h>
#import <Foundation/NSArray.h>
@interface SoObjectWebDAVDispatcher (ActiveSync)
- (id)_callObjectMethod:(NSString *)_method inContext:(WOContext *)_ctx;
- (id) doOPTIONS:(WOContext *)_ctx;
@end
@implementation SoObjectWebDAVDispatcher (ActiveSync)
- (id) doOPTIONS:(WOContext *)_ctx
{
WOResponse *response;
/*
See example: http://msdn.microsoft.com/en-us/library/ee204257(v=exchg.80).aspx
*/
if ([[[_ctx request] requestHandlerKey] isEqualToString: @"Microsoft-Server-ActiveSync"])
{
response = [_ctx response];
[response setStatus: 200];
[response setHeader: @"private" forKey: @"Cache-Control"];
[response setHeader: @"OPTIONS, POST" forKey: @"Allow"];
[response setHeader: @"14.1" forKey: @"MS-Server-ActiveSync"];
[response setHeader: @"2.0,2.1,2.5,12.0,12.1,14.0,14.1" forKey: @"MS-ASProtocolVersions"];
[response setHeader: @"Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteCollection,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,MoveItems,GetItemEstimate,MeetingResponse,Search,Settings,Ping,ItemOperations,ResolveRecipients,ValidateCert" forKey: @"MS-ASProtocolCommands"];
[response setHeader: @"OPTIONS, POST" forKey: @"Public"];
}
else
{
NSArray *tmp;
id result;
/* this checks whether the object provides a specific OPTIONS method */
if ((result = [self _callObjectMethod:@"OPTIONS" inContext:_ctx]) != nil)
return result;
response = [_ctx response];
[response setStatus:200 /* OK */];
if ((tmp = [self->object davAllowedMethodsInContext:_ctx]) != nil)
[response setHeader:[tmp componentsJoinedByString:@", "] forKey:@"allow"];
if ([[[_ctx request] clientCapabilities] isWebFolder]) {
/*
As described over here:
http://teyc.editthispage.com/2005/06/02
This page also says that: "MS-Auth-Via header is not required to work
with Web Folders".
*/
[response setHeader:[tmp componentsJoinedByString:@", "] forKey:@"public"];
}
if ((tmp = [self->object davComplianceClassesInContext:_ctx]) != nil)
[response setHeader:[tmp componentsJoinedByString:@", "] forKey:@"dav"];
}
return response;
}
@end
+34
View File
@@ -0,0 +1,34 @@
include ../config.make
include $(GNUSTEP_MAKEFILES)/common.make
include ../Version
NEEDS_GUI=no
BUNDLE_EXTENSION = .SOGo
BUNDLE_INSTALL_DIR = $(SOGO_LIBDIR)
WOBUNDLE_EXTENSION = $(BUNDLE_EXTENSION)
WOBUNDLE_INSTALL_DIR = $(BUNDLE_INSTALL_DIR)
# SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib
ADDITIONAL_INCLUDE_DIRS += \
-I.. \
-I../.. \
-I../../SOPE
ADDITIONAL_LIB_DIRS += \
-L../SoObjects/SOGo/SOGo.framework/Versions/Current/sogo \
-L../SoObjects/SOGo/$(GNUSTEP_OBJ_DIR)/ \
-L../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ \
-L/usr/local/lib \
-Wl,-rpath,$(GNUSTEP_SYSTEM_LIBRARIES)/sogo
BUNDLE_LIBS += \
-lSOGo \
-lGDLContentStore \
-lGDLAccess \
-lNGObjWeb \
-lNGCards -lNGMime -lNGLdap \
-lNGStreams -lNGExtensions -lEOControl \
-lDOM -lSaxObjC -lSBJson
ADDITIONAL_BUNDLE_LIBS += $(BUNDLE_LIBS)
+46
View File
@@ -0,0 +1,46 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ICALALARMACTIVESYNC_H__
#define __ICALALARMACTIVESYNC_H__
#import <NGCards/iCalAlarm.h>
@class NSString;
@class WOContext;
@interface iCalAlarm (ActiveSync)
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context;
- (void) takeActiveSyncValues: (NSDictionary *) theValues
inContext: (WOContext *) context;
@end
#endif
+106
View File
@@ -0,0 +1,106 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "iCalAlarm+ActiveSync.h"
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <NGExtensions/NSString+misc.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGCards/iCalAlarm.h>
#import <NGCards/iCalEvent.h>
#import <NGCards/iCalTrigger.h>
@implementation iCalAlarm (ActiveSync)
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context
{
NSMutableString *s;
s = [NSMutableString string];
if ([[self action] caseInsensitiveCompare: @"DISPLAY"] == NSOrderedSame)
{
NSCalendarDate *nextAlarmDate;
NSInteger delta;
nextAlarmDate = [self nextAlarmDate];
delta = (int)(([[(iCalEvent *)parent startDate] timeIntervalSince1970] - [nextAlarmDate timeIntervalSince1970])/60);
// don't send negative reminder - not supported
if (delta > 0)
[s appendFormat: @"<Reminder xmlns=\"Calendar:\">%d</Reminder>", delta];
}
return s;
}
- (void) takeActiveSyncValues: (NSDictionary *) theValues
inContext: (WOContext *) context
{
iCalTrigger *trigger;
id o;
o = [theValues objectForKey: @"Reminder"];
// Outlook: if reminder is set to 0 minutes before start save it as 1 minute since -> 0 minutes in not accepted by SOGo
if ([o isEqualToString: @"0"])
o = @"1";
trigger = [iCalTrigger elementWithTag: @"TRIGGER"];
[trigger setValueType: @"DURATION"];
[self setTrigger: trigger];
[self setAction: @"DISPLAY"];
// SOGo web ui only supports 1w but not 2w (custom reminder only supports min/hours/days)
// 1week = -P1W
// 2weeks > -PxD
// xdays > -PxD
// xhours -> -PTxH
// xmin -> -PTxM
if ([o intValue] == 10080)
[trigger setSingleValue: [NSString stringWithFormat: @"-P1W" ] forKey: @""];
else
{
if (([o intValue] % 1440) == 0)
[trigger setSingleValue: [NSString stringWithFormat: @"-P%dD", ([o intValue] / 1440)] forKey: @""];
else
{
if (([o intValue] % 60) == 0)
[trigger setSingleValue: [NSString stringWithFormat: @"-PT%dH", ([o intValue] / 60)] forKey: @""];
else
[trigger setSingleValue: [NSString stringWithFormat: @"-PT%@M", o] forKey: @""];
}
}
}
@end
+47
View File
@@ -0,0 +1,47 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ICALEVENTACTIVESYNC_H__
#define __ICALEVENTACTIVESYNC_H__
#import <NGCards/iCalEvent.h>
@class NSString;
@class WOContext;
@interface iCalEvent (ActiveSync)
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context;
- (void) takeActiveSyncValues: (NSDictionary *) theValues
inContext: (WOContext *) context;
@end
#endif
+552
View File
@@ -0,0 +1,552 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "iCalEvent+ActiveSync.h"
#import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSDate.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <Foundation/NSTimeZone.h>
#import <NGExtensions/NSString+misc.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGCards/iCalCalendar.h>
#import <NGCards/iCalDateTime.h>
#import <NGCards/iCalPerson.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <Appointments/iCalEntityObject+SOGo.h>
#include "iCalAlarm+ActiveSync.h"
#include "iCalRecurrenceRule+ActiveSync.h"
#include "iCalTimeZone+ActiveSync.h"
#include "NSDate+ActiveSync.h"
#include "NSString+ActiveSync.h"
@implementation iCalEvent (ActiveSync)
- (int) _attendeeStatus: (iCalPerson *) attendee
{
int attendee_status;
attendee_status = 5;
if ([[attendee partStat] caseInsensitiveCompare: @"ACCEPTED"] == NSOrderedSame)
attendee_status = 3;
else if ([[attendee partStat] caseInsensitiveCompare: @"DECLINED"] == NSOrderedSame)
attendee_status = 4;
else if ([[attendee partStat] caseInsensitiveCompare: @"TENTATIVE"] == NSOrderedSame)
attendee_status = 2;
return attendee_status;
}
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context
{
NSMutableString *s;
NSArray *attendees;
iCalPerson *organizer, *attendee;
iCalTimeZone *tz;
id o;
int v;
NSTimeZone *userTimeZone;
userTimeZone = [[[context activeUser] userDefaults] timeZone];
s = [NSMutableString string];
[s appendFormat: @"<AllDayEvent xmlns=\"Calendar:\">%d</AllDayEvent>", ([self isAllDay] ? 1 : 0)];
// DTStamp -- http://msdn.microsoft.com/en-us/library/ee219470(v=exchg.80).aspx
if ([self timeStampAsDate])
[s appendFormat: @"<DTStamp xmlns=\"Calendar:\">%@</DTStamp>", [[self timeStampAsDate] activeSyncRepresentationWithoutSeparatorsInContext: context]];
else if ([self created])
[s appendFormat: @"<DTStamp xmlns=\"Calendar:\">%@</DTStamp>", [[self created] activeSyncRepresentationWithoutSeparatorsInContext: context]];
// StartTime -- http://msdn.microsoft.com/en-us/library/ee157132(v=exchg.80).aspx
if ([self startDate])
{
if ([self isAllDay])
[s appendFormat: @"<StartTime xmlns=\"Calendar:\">%@</StartTime>",
[[[self startDate] dateByAddingYears: 0 months: 0 days: 0
hours: 0 minutes: 0
seconds: ([userTimeZone secondsFromGMTForDate: [self startDate]])*-1]
activeSyncRepresentationWithoutSeparatorsInContext: context]];
else
[s appendFormat: @"<StartTime xmlns=\"Calendar:\">%@</StartTime>", [[self startDate] activeSyncRepresentationWithoutSeparatorsInContext: context]];
}
// EndTime -- http://msdn.microsoft.com/en-us/library/ee157945(v=exchg.80).aspx
if ([self endDate])
{
if ([self isAllDay])
[s appendFormat: @"<EndTime xmlns=\"Calendar:\">%@</EndTime>",
[[[self endDate] dateByAddingYears: 0 months: 0 days: 0
hours: 0 minutes: 0
seconds: ([userTimeZone secondsFromGMTForDate: [self endDate]])*-1]
activeSyncRepresentationWithoutSeparatorsInContext: context]];
else
[s appendFormat: @"<EndTime xmlns=\"Calendar:\">%@</EndTime>", [[self endDate] activeSyncRepresentationWithoutSeparatorsInContext: context]];
}
// Timezone
tz = [(iCalDateTime *)[self firstChildWithTag: @"dtstart"] timeZone];
if (!tz)
tz = [iCalTimeZone timeZoneForName: [userTimeZone name]];
[s appendFormat: @"<TimeZone xmlns=\"Calendar:\">%@</TimeZone>", [tz activeSyncRepresentationInContext: context]];
// Organizer and other invitations related properties
if ((organizer = [self organizer]))
{
o = [organizer rfc822Email];
if ([o length])
{
[s appendFormat: @"<Organizer_Email xmlns=\"Calendar:\">%@</Organizer_Email>", o];
o = [organizer cn];
if ([o length])
[s appendFormat: @"<Organizer_Name xmlns=\"Calendar:\">%@</Organizer_Name>", o];
}
}
// Attendees
attendees = [self attendees];
if ([attendees count])
{
int i, attendee_status, attendee_type;
[s appendString: @"<Attendees xmlns=\"Calendar:\">"];
for (i = 0; i < [attendees count]; i++)
{
[s appendString: @"<Attendee xmlns=\"Calendar:\">"];
attendee = [attendees objectAtIndex: i];
[s appendFormat: @"<Attendee_Email xmlns=\"Calendar:\">%@</Attendee_Email>", [attendee rfc822Email]];
[s appendFormat: @"<Attendee_Name xmlns=\"Calendar:\">%@</Attendee_Name>", [[attendee cn] activeSyncRepresentationInContext: context]];
attendee_status = [self _attendeeStatus: attendee];
[s appendFormat: @"<Attendee_Status xmlns=\"Calendar:\">%d</Attendee_Status>", attendee_status];
// FIXME: handle resource
if ([[attendee role] caseInsensitiveCompare: @"REQ-PARTICIPANT"] == NSOrderedSame)
attendee_type = 1;
else
attendee_type = 2;
[s appendFormat: @"<Attendee_Type xmlns=\"Calendar:\">%d</Attendee_Type>", attendee_type];
[s appendString: @"</Attendee>"];
}
[s appendString: @"</Attendees>"];
}
// This depends on the 'NEEDS-ACTION' parameter.
// This will trigger the SendMail command
if ([self userIsAttendee: [context activeUser]])
{
iCalPerson *attendee;
int attendee_status;
attendee = [self userAsAttendee: [context activeUser]];
attendee_status = [self _attendeeStatus: attendee];
[s appendFormat: @"<ResponseRequested xmlns=\"Calendar:\">%d</ResponseRequested>", 1];
[s appendFormat: @"<ResponseType xmlns=\"Calendar:\">%d</ResponseType>", attendee_status];
[s appendFormat: @"<MeetingStatus xmlns=\"Calendar:\">%d</MeetingStatus>", 3];
[s appendFormat: @"<DisallowNewTimeProposal xmlns=\"Calendar:\">%d</DisallowNewTimeProposal>", 1];
// BusyStatus -- http://msdn.microsoft.com/en-us/library/ee202290(v=exchg.80).aspx
[s appendFormat: @"<BusyStatus xmlns=\"Calendar:\">%d</BusyStatus>", 2];
}
// Subject -- http://msdn.microsoft.com/en-us/library/ee157192(v=exchg.80).aspx
if ([[self summary] length])
[s appendFormat: @"<Subject xmlns=\"Calendar:\">%@</Subject>", [[self summary] activeSyncRepresentationInContext: context]];
// Location
if ([[self location] length])
[s appendFormat: @"<Location xmlns=\"Calendar:\">%@</Location>", [[self location] activeSyncRepresentationInContext: context]];
// Importance - NOT SUPPORTED - DO NOT ENABLE
//o = [self priority];
//if ([o isEqualToString: @"9"])
// v = 0;
//else if ([o isEqualToString: @"1"])
// v = 2;
//else
// v = 1;
//[s appendFormat: @"<Importance xmlns=\"Calendar:\">%d</Importance>", v];
// UID -- http://msdn.microsoft.com/en-us/library/ee159919(v=exchg.80).aspx
if ([[self uid] length])
[s appendFormat: @"<UID xmlns=\"Calendar:\">%@</UID>", [self uid]];
// Sensitivity
if ([[self accessClass] isEqualToString: @"PRIVATE"])
v = 2;
if ([[self accessClass] isEqualToString: @"CONFIDENTIAL"])
v = 3;
else
v = 0;
[s appendFormat: @"<Sensitivity xmlns=\"Calendar:\">%d</Sensitivity>", v];
// Reminder -- http://msdn.microsoft.com/en-us/library/ee219691(v=exchg.80).aspx
// TODO: improve this to handle more alarm types
if ([self hasAlarms])
{
iCalAlarm *alarm;
alarm = [self firstDisplayOrAudioAlarm];
[s appendString: [alarm activeSyncRepresentationInContext: context]];
}
// Recurrence rules
if ([self isRecurrent])
{
[s appendString: [[[self recurrenceRules] lastObject] activeSyncRepresentationInContext: context]];
}
// Comment
o = [self comment];
if ([o length])
{
o = [o activeSyncRepresentationInContext: context];
[s appendString: @"<Body xmlns=\"AirSyncBase:\">"];
[s appendFormat: @"<Type>%d</Type>", 1];
[s appendFormat: @"<EstimatedDataSize>%d</EstimatedDataSize>", [o length]];
[s appendFormat: @"<Truncated>%d</Truncated>", 0];
[s appendFormat: @"<Data>%@</Data>", o];
[s appendString: @"</Body>"];
}
[s appendFormat: @"<NativeBodyType xmlns=\"AirSyncBase:\">%d</NativeBodyType>", 1];
return s;
}
//
// To understand meeting requests/responses, see:
//
// http://blogs.msdn.com/b/exchangedev/archive/2011/07/22/working-with-meeting-requests-in-exchange-activesync.aspx
// http://blogs.msdn.com/b/exchangedev/archive/2011/07/29/working-with-meeting-responses-in-exchange-activesync.aspx
//
//
// Here is an example of a Sync call when sogo10 accepts an invitation from sogo3:
//
// <Change>
// <ServerId>2978-52EA9D00-1-A253E70.ics</ServerId>
// <ApplicationData>
// <TimeZone xmlns="Calendar:">LAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAABAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAACAAIAAAAAAAAAxP///w==</TimeZone>
// <AllDayEvent xmlns="Calendar:">0</AllDayEvent>
// <StartTime xmlns="Calendar:">20140207T130000Z</StartTime>
// <EndTime xmlns="Calendar:">20140207T140000Z</EndTime>
// <DTStamp xmlns="Calendar:">20140130T185245Z</DTStamp>
// <Subject xmlns="Calendar:">test 8</Subject>
// <Sensitivity xmlns="Calendar:">0</Sensitivity>
// <Body xmlns="AirSyncBase:">
// <Type>1</Type>
// <Data/>
// </Body>
// <Organizer_Email xmlns="Calendar:">sogo3@example.com</Organizer_Email>
// <UID xmlns="Calendar:">2978-52EA9D00-1-A253E70</UID>
// <Attendees xmlns="Calendar:">
// <Attendee>
// <Attendee_Name>sogo10</Attendee_Name>
// <Attendee_Email>sogo10@example.com</Attendee_Email>
// <Attendee_Type>1</Attendee_Type>
// </Attendee>
// </Attendees>
// <BusyStatus xmlns="Calendar:">2</BusyStatus>
// <MeetingStatus xmlns="Calendar:">3</MeetingStatus>
// <Organizer_Name xmlns="Calendar:">Wolfgang Fritz</Organizer_Name>
// </ApplicationData>
// </Change>
//
- (void) takeActiveSyncValues: (NSDictionary *) theValues
inContext: (WOContext *) context
{
iCalDateTime *start, *end;
NSTimeZone *userTimeZone;
iCalTimeZone *tz;
id o;
NSInteger tzOffset;
BOOL isAllDay;
if ((o = [theValues objectForKey: @"UID"]))
[self setUid: o];
// FIXME: merge with iCalToDo
if ((o = [theValues objectForKey: @"Subject"]))
[self setSummary: o];
isAllDay = NO;
if ([[theValues objectForKey: @"AllDayEvent"] intValue])
{
isAllDay = YES;
}
//
// 0- free, 1- tentative, 2- busy and 3- out of office
//
if ((o = [theValues objectForKey: @"BusyStatus"]))
{
[o intValue];
}
//
// 0- normal, 1- personal, 2- private and 3-confidential
//
if ((o = [theValues objectForKey: @"Sensitivy"]))
{
switch ([o intValue])
{
case 2:
[self setAccessClass: @"PRIVATE"];
break;
case 3:
[self setAccessClass: @"CONFIDENTIAL"];
break;
case 0:
case 1:
default:
[self setAccessClass: @"PUBLIC"];
}
}
// We ignore TimeZone sent by mobile devices for now.
// Some Windows devices don't send during event updates.
//if ((o = [theValues objectForKey: @"TimeZone"]))
// {
userTimeZone = [[[context activeUser] userDefaults] timeZone];
tz = [iCalTimeZone timeZoneForName: [userTimeZone name]];
[(iCalCalendar *) parent addTimeZone: tz];
//}
// FIXME: merge with iCalToDo
if ((o = [[theValues objectForKey: @"Body"] objectForKey: @"Data"]))
[self setComment: o];
if ((o = [theValues objectForKey: @"Location"]))
[self setLocation: o];
if ((o = [theValues objectForKey: @"StartTime"]))
{
o = [o calendarDate];
start = (iCalDateTime *) [self uniqueChildWithTag: @"dtstart"];
[start setTimeZone: tz];
if (isAllDay)
{
tzOffset = [userTimeZone secondsFromGMTForDate: o];
o = [o dateByAddingYears: 0 months: 0 days: 0
hours: 0 minutes: 0
seconds: tzOffset];
[start setDate: o];
[start setTimeZone: nil];
}
else
{
tzOffset = [userTimeZone secondsFromGMTForDate: o];
o = [o dateByAddingYears: 0 months: 0 days: 0
hours: 0 minutes: 0
seconds: tzOffset];
[start setDateTime: o];
}
}
if ((o = [theValues objectForKey: @"EndTime"]))
{
o = [o calendarDate];
end = (iCalDateTime *) [self uniqueChildWithTag: @"dtend"];
[end setTimeZone: tz];
if (isAllDay)
{
tzOffset = [userTimeZone secondsFromGMTForDate: o];
o = [o dateByAddingYears: 0 months: 0 days: 0
hours: 0 minutes: 0
seconds: tzOffset];
[end setDate: o];
[end setTimeZone: nil];
}
else
{
tzOffset = [userTimeZone secondsFromGMTForDate: o];
o = [o dateByAddingYears: 0 months: 0 days: 0
hours: 0 minutes: 0
seconds: tzOffset];
[end setDateTime: o];
}
}
//
// If an alarm is deinfed with an action != DISPLAY, we ignore the alarm - don't want to overwrite.
//
if ([self hasAlarms] && [[[[self alarms] objectAtIndex: 0] action] caseInsensitiveCompare: @"DISPLAY"] != NSOrderedSame)
{
// Ignore the alarm for now
}
else if ((o = [theValues objectForKey: @"Reminder"]))
{
// NOTE: Outlook sends a 15 min reminder (18 hour for allday) if no reminder is specified
// although no default reminder is defined (File -> Options -> Clendar -> Calendar Options - > Default Reminders)
//
// http://answers.microsoft.com/en-us/office/forum/office_2013_release-outlook/desktop-outlook-calendar-creates-entries-with/9aef72d8-81bb-4a32-a6ab-bf7d216fb811?page=5&tm=1395690285088
//
iCalAlarm *alarm;
alarm = [[iCalAlarm alloc] init];
[alarm takeActiveSyncValues: theValues inContext: context];
[self removeAllAlarms];
[self addToAlarms: alarm];
RELEASE(alarm);
}
else
{
// We remove existing alarm since no reminder in the ActiveSync payload
[self removeAllAlarms];
}
// Recurrence
if ((o = [theValues objectForKey: @"Recurrence"]))
{
iCalRecurrenceRule *rule;
rule = [[iCalRecurrenceRule alloc] init];
[self setRecurrenceRules: [NSArray arrayWithObject: rule]];
RELEASE(rule);
[rule takeActiveSyncValues: o inContext: context];
}
// Organizer - we don't touch the value unless we're the organizer
if ((o = [theValues objectForKey: @"Organizer_Email"]) &&
([self userIsOrganizer: [context activeUser]] || [[context activeUser] hasEmail: o]))
{
iCalPerson *person;
person = [iCalPerson elementWithTag: @"organizer"];
[person setEmail: o];
[person setCn: [theValues objectForKey: @"Organizer_Name"]];
[person setPartStat: @"ACCEPTED"];
[self setOrganizer: person];
}
//
// iOS is plain stupid here. It seends event invitations with no Organizer.
// We check this corner-case and if MeetingStatus == 1 (see http://msdn.microsoft.com/en-us/library/ee219342(v=exchg.80).aspx or details)
// and there's no organizer, we fake one.
//
if ((o = [theValues objectForKey: @"MeetingStatus"]))
{
if ([o intValue] == 1 && ![theValues objectForKey: @"Organizer_Email"])
{
iCalPerson *person;
person = [iCalPerson elementWithTag: @"organizer"];
[person setEmail: [[[context activeUser] primaryIdentity] objectForKey: @"email"]];
[person setCn: [[context activeUser] cn]];
[person setPartStat: @"ACCEPTED"];
[self setOrganizer: person];
}
}
// Attendees - we don't touch the values if we're an attendee. This is gonna
// be done automatically by the ActiveSync client when invoking MeetingResponse.
if (![self userIsAttendee: [context activeUser]])
{
// Windows phones sens sometimes an empty Attendees tag.
// We check it's an array before processing it.
if ((o = [theValues objectForKey: @"Attendees"])&& [o isKindOfClass: [NSArray class]])
{
NSMutableArray *attendees;
NSDictionary *attendee;
iCalPerson *person;
int status, i;
attendees = [NSMutableArray array];
for (i = 0; i < [o count]; i++)
{
// Each attendee has is a dictionary similar to this:
// { "Attendee_Email" = "sogo3@example.com"; "Attendee_Name" = "Wolfgang Fritz"; "Attendee_Status" = 5; "Attendee_Type" = 1; }
attendee = [o objectAtIndex: i];
person = [iCalPerson elementWithTag: @"attendee"];
[person setCn: [attendee objectForKey: @"Attendee_Name"]];
[person setEmail: [attendee objectForKey: @"Attendee_Email"]];
status = [[attendee objectForKey: @"Attendee_Status"] intValue];
switch (status)
{
case 2:
[person setPartStat: @"TENTATIVE"];
break;
case 3:
[person setPartStat: @"ACCEPTED"];
break;
case 4:
[person setPartStat: @"DECLINED"];
break;
case 0:
case 5:
default:
[person setPartStat: @"NEEDS-ACTION"];
break;
}
// FIXME: handle Attendee_Type
[attendees addObject: person];
}
[self setAttendees: attendees];
}
}
}
@end
@@ -0,0 +1,48 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ICALRECURRENCERULEACTIVESYNC_H__
#define __ICALRECURRENCERULEACTIVESYNC_H__
#import <NGCards/iCalRecurrenceRule.h>
@class NSDictionary;
@class NSString;
@class WOContext;
@interface iCalRecurrenceRule (ActiveSync)
- (NSString *) activeSyncRepresentationInContext:(WOContext *) context;
- (void) takeActiveSyncValues: (NSDictionary *) theValues
inContext: (WOContext *) context;
@end
#endif
+372
View File
@@ -0,0 +1,372 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "iCalRecurrenceRule+ActiveSync.h"
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <NGCards/iCalEvent.h>
#import <NGCards/iCalByDayMask.h>
#import "NSCalendarDate+ActiveSync.h"
#import "NSDate+ActiveSync.h"
@implementation iCalRecurrenceRule (ActiveSync)
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context
{
NSMutableString *s;
int type;
s = [NSMutableString string];
[s appendString: @"<Recurrence xmlns=\"Calendar:\">"];
// 0 -> daily, 1 -> weekly, 2 -> montly, 5 -> yearly
type = 0;
if ([self frequency] == iCalRecurrenceFrequenceDaily)
{
type = 0;
// 1 -> sunday, 2 -> monday, 4 -> tuesday, 8 -> wednesday, 16 -> thursday, 32 -> friday, 64 -> saturday, 127 -> last day of month (montly or yearl recurrences only)
if ([[self byDayMask] isWeekDays])
{
[s appendFormat: @"<Recurrence_DayOfWeek xmlns=\"Calendar:\">%d</Recurrence_DayOfWeek>", (2|4|8|16|32)];
}
else
{
[s appendFormat: @"<Recurrence_Interval xmlns=\"Calendar:\">%d</Recurrence_Interval>", [self repeatInterval]];
}
}
else if ([self frequency] == iCalRecurrenceFrequenceWeekly)
{
iCalWeekOccurrences *occurrences;
int i, v;
type = 1;
occurrences = [[self byDayMask] weekDayOccurrences];
v = 0;
if (occurrences)
{
for (i = 0; i < 7; i++)
{
if (occurrences[0][i])
v += (1 << i);
}
}
else
{
// No byDayMask, we take the event's start date to compute the DayOfWeek
// 0 == Sunday, 6 == Saturday
v = (1 << [[[self parent] startDate] dayOfWeek]);
}
[s appendFormat: @"<Recurrence_DayOfWeek xmlns=\"Calendar:\">%d</Recurrence_DayOfWeek>", v];
[s appendFormat: @"<Recurrence_Interval xmlns=\"Calendar:\">%d</Recurrence_Interval>", [self repeatInterval]];
}
else if ([self frequency] == iCalRecurrenceFrequenceMonthly)
{
if ([[self byDay] length])
{
int firstOccurrence;
iCalByDayMask *dm;
type = 3; // recurs monthly on the nth day
dm = [self byDayMask];
firstOccurrence = [dayMask firstOccurrence];
// Handle the case for "Last day of the month"
if (firstOccurrence < 0)
firstOccurrence = 5;
[s appendFormat: @"<Recurrence_DayOfWeek xmlns=\"Calendar:\">%d</Recurrence_DayOfWeek>", (1 << [dm firstDay])];
[s appendFormat: @"<Recurrence_WeekOfMonth xmlns=\"Calendar:\">%d</Recurrence_WeekOfMonth>", firstOccurrence];
}
else if ([[self byMonthDay] count])
{
NSArray *days;
type = 2; // recurs monthly
days = [self byMonthDay];
if ([days count] > 0 && [[days objectAtIndex: 0] intValue] < 0)
{
// Last day of the month
iCalByDayMask *dm;
dm = [self byDayMask];
[s appendFormat: @"<Recurrence_DayOfWeek xmlns=\"Calendar:\">%d</Recurrence_DayOfWeek>", (1 << [dm firstDay])];
[s appendFormat: @"<Recurrence_WeekOfMonth xmlns=\"Calendar:\">%d</Recurrence_WeekOfMonth>", 5];
}
else
{
// Unsupported rule in ActiveSync/Outlook. Rule that says "Repeat on the 7th and 8th of each month".
// FIXME
}
}
else
{
// Simple reccurrence rule of type "Monthly"
type = 2;
[s appendFormat: @"<Recurrence_DayOfMonth xmlns=\"Calendar:\">%d</Recurrence_DayOfMonth>",
[[[self parent] startDate] dayOfMonth]];
}
}
else if ([self frequency] == iCalRecurrenceFrequenceYearly)
{
type = 6; // Yearly on the nth day
if ([[self flattenedValuesForKey: @"bymonth"] length])
{
if ([[self byDay] length])
{
int firstOccurrence;
iCalByDayMask *dm;
dm = [self byDayMask];
firstOccurrence = [dm firstOccurrence];
if (firstOccurrence < 0)
firstOccurrence = 5;
[s appendFormat: @"<Recurrence_DayOfWeek xmlns=\"Calendar:\">%d</Recurrence_DayOfWeek>", (1 << [dm firstDay])];
[s appendFormat: @"<Recurrence_WeekOfMonth xmlns=\"Calendar:\">%d</Recurrence_WeekOfMonth>", firstOccurrence];
[s appendFormat: @"<Recurrence_MonthOfYear xmlns=\"Calendar:\">%@</Recurrence_MonthOfYear>",
[self flattenedValuesForKey: @"bymonth"]];
}
else
{
type = 5; // Yearly
[s appendFormat: @"<Recurrence_DayOfMonth xmlns=\"Calendar:\">%@</Recurrence_DayOfMonth>",
[self flattenedValuesForKey: @"bymonthday"]];
[s appendFormat: @"<Recurrence_MonthOfYear xmlns=\"Calendar:\">%@</Recurrence_MonthOfYear>",
[self flattenedValuesForKey: @"bymonth"]];
}
}
else
type = 5;
}
[s appendFormat: @"<Recurrence_Type xmlns=\"Calendar:\">%d</Recurrence_Type>", type];
// Occurrences / Until
//[s appendFormat: @"<Recurrence_Occurrences xmlns=\"Calendar:\">%d</Recurrence_Occurrences>", 5];
if ([self repeatCount])
{
[s appendFormat: @"<Recurrence_Occurrences xmlns=\"Calendar:\">%@</Recurrence_Occurrences>",
[self flattenedValuesForKey: @"count"]];
}
else if ([self untilDate])
{
NSCalendarDate *date;
date = [self untilDate];
//ud = [[context activeUser] userDefaults];
//[date setTimeZone: [ud timeZone]];
[s appendFormat: @"<Recurrence_Until xmlns=\"Calendar:\">%@</Recurrence_Until>",
[date activeSyncRepresentationWithoutSeparatorsInContext: context]];
}
[s appendString: @"</Recurrence>"];
return s;
}
//
//
//
- (void) _setByDayFromValues: (NSDictionary *) theValues
{
NSString *day;
id o;
unsigned int day_of_week;
int i, week_of_month;
o = [theValues objectForKey: @"Recurrence_DayOfWeek"];
// The documentation says WeekOfMonth must be between 1 and 5. The value
// 5 means "last week of month"
week_of_month = [[theValues objectForKey: @"Recurrence_WeekOfMonth"] intValue];
if (week_of_month > 4)
week_of_month = -1;
// We find the correct day of the week
day_of_week = [o intValue];
for (i = 0; i < 7; i++)
{
if ((1<<i) == day_of_week)
{
day_of_week = i;
break;
}
}
day = [self iCalRepresentationForWeekDay: i];
[self setSingleValue: [NSString stringWithFormat: @"%d%@",
week_of_month, day]
forKey: @"byday"];
}
- (void) _setByMonthFromValues: (NSDictionary *) theValues
{
unsigned int month_of_year;
month_of_year = [[theValues objectForKey: @"Recurrence_MonthOfYear"] intValue];
[self setSingleValue: [NSString stringWithFormat: @"%d", month_of_year]
forKey: @"bymonth"];
}
//
//
//
- (void) takeActiveSyncValues: (NSDictionary *) theValues
inContext: (WOContext *) context
{
id o;
int recurrenceType;
recurrenceType = [[theValues objectForKey: @"Recurrence_Type"] intValue];
if ((o = [theValues objectForKey: @"Recurrence_Interval"]))
{
[self setRepeatInterval: [o intValue]];
}
else
[self setRepeatInterval: 1];
switch (recurrenceType)
{
//
// Daily
//
case 0:
[self setFrequency: iCalRecurrenceFrequenceDaily];
// Every weekday
if ((o = [theValues objectForKey: @"Recurrence_DayOfWeek"]))
{
[self setByDayMask: [iCalByDayMask byDayMaskWithWeekDays]];
}
break;
//
// Weekly
//
case 1:
[self setFrequency: iCalRecurrenceFrequenceWeekly];
// 42 == Every Monday, Wednesday and Friday, for example
if ((o = [theValues objectForKey: @"Recurrence_DayOfWeek"]))
{
iCalWeekOccurrences days;
unsigned int i, v;
memset(days, 0, 7 * sizeof(iCalWeekOccurrence));
v = [o intValue];
for (i = 0; i < 7; i++)
{
if (v & (1<<i))
days[i] = iCalWeekOccurrenceAll;
}
[self setByDayMask: [iCalByDayMask byDayMaskWithDays: days]];
}
break;
//
// Montly
//
case 2:
case 3:
[self setFrequency: iCalRecurrenceFrequenceMonthly];
// The 5th of every X month(s)
if ((o = [theValues objectForKey: @"Recurrence_DayOfMonth"]))
{
[self setValues: [NSArray arrayWithObject: o]
atIndex: 0 forKey: @"bymonthday"];
}
// The 3rd Thursay every X month(s)
else if ((o = [theValues objectForKey: @"Recurrence_DayOfWeek"]))
{
[self _setByDayFromValues: theValues];
}
break;
//
// Yearly
//
case 5:
case 6:
default:
[self setFrequency: iCalRecurrenceFrequenceYearly];
// On April 19th
if ((o = [theValues objectForKey: @"Recurrence_DayOfMonth"]))
{
[self setValues: [NSArray arrayWithObject: o] atIndex: 0
forKey: @"bymonthday"];
[self _setByMonthFromValues: theValues];
}
else
{
// On the Second Wednesday of April
[self _setByDayFromValues: theValues];
[self _setByMonthFromValues: theValues];
}
break;
}
if ((o = [theValues objectForKey: @"Recurrence_Occurrences"]))
{
[self setRepeatCount: [o intValue]];
}
else if ((o = [theValues objectForKey: @"Recurrence_Until"]))
{
[self setUntilDate: [o calendarDate]];
}
}
@end
+44
View File
@@ -0,0 +1,44 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ICALTIMEZONEACTIVESYNC_H__
#define __ICALTIMEZONEACTIVESYNC_H__
#import <NGCards/iCalTimeZone.h>
@class NSString;
@class WOContext;
@interface iCalTimeZone (ActiveSync)
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context;
@end
#endif
+167
View File
@@ -0,0 +1,167 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "iCalTimeZone+ActiveSync.h"
#include <Foundation/NSArray.h>
#include <Foundation/NSCalendarDate.h>
#include <Foundation/NSData.h>
#include <Foundation/NSDate.h>
#include <Foundation/NSString.h>
#import <NGCards/iCalByDayMask.h>
#import <NGCards/iCalTimeZonePeriod.h>
#import <NGCards/iCalRecurrenceRule.h>
#import <NGExtensions/NGBase64Coding.h>
#include "NSData+ActiveSync.h"
struct SYSTEMTIME {
uint16_t wYear;
uint16_t wMonth;
uint16_t wDayOfWeek;
uint16_t wDay;
uint16_t wHour;
uint16_t wMinute;
uint16_t wSecond;
uint16_t wMilliseconds;
};
@interface iCalTimeZonePeriod (ActiveSync)
- (void) _fillTZDate: (struct SYSTEMTIME *) tzData;
@end
@implementation iCalTimeZonePeriod (ActiveSync)
//
// FIXME - combine with iCalTimeZone+MAPIStore.m
//
- (void) _fillTZDate: (struct SYSTEMTIME *) tzData
{
iCalRecurrenceRule *rrule;
NSArray *byMonth;
iCalByDayMask *mask;
NSCalendarDate *dateValue;
rrule = [self recurrenceRule];
byMonth = [rrule byMonth];
if ([byMonth count] > 0)
{
tzData->wYear = 0;
tzData->wMonth = [[byMonth objectAtIndex: 0] intValue];
mask = [rrule byDayMask];
tzData->wDayOfWeek = [mask firstDay];
tzData->wDay = ([mask firstOccurrence] == -1) ? 5 : [mask firstOccurrence];
dateValue = [self startDate];
tzData->wHour = [dateValue hourOfDay];
tzData->wMinute = [dateValue minuteOfHour];
tzData->wSecond = [dateValue secondOfMinute];
tzData->wMilliseconds = 0;
}
}
@end
@implementation iCalTimeZone (ActiveSync)
//
// FIXME - combine with iCalTimeZone+MAPIStore.m
//
- (iCalTimeZonePeriod *) _mostRecentPeriodWithName: (NSString *) periodName
{
NSArray *periods;
iCalTimeZonePeriod *period;
NSUInteger max;
periods = [self childrenWithTag: periodName];
max = [periods count];
if (max > 0)
{
periods = [periods sortedArrayUsingSelector: @selector (compare:)];
period = (iCalTimeZonePeriod *) [periods objectAtIndex: (max - 1)];
}
else
period = nil;
return period;
}
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context
{
iCalTimeZonePeriod *period;
NSMutableData *bytes;
uint32_t lBias;
uint32_t lStandardBias;
uint32_t lDaylightBias;
//uint16_t wStandardYear;
struct SYSTEMTIME stStandardDate;
//uint16_t wDaylightYear;
struct SYSTEMTIME stDaylightDate;
char standardName[64], daylightName[64];
bytes = [NSMutableData data];
memset(standardName, 0, 64);
memset(daylightName, 0, 64);
lStandardBias = 0;
period = [self _mostRecentPeriodWithName: @"STANDARD"];
lBias = -[period secondsOffsetFromGMT] / 60;
[period _fillTZDate: &stStandardDate];
period = [self _mostRecentPeriodWithName: @"DAYLIGHT"];
if (!period)
stStandardDate.wMonth = 0;
lDaylightBias = (uint32_t) -([period secondsOffsetFromGMT] / 60) - lBias;
[period _fillTZDate: &stDaylightDate];
//wStandardYear = stStandardDate.wYear;
//wDaylightYear = stDaylightDate.wYear;
// We build the timezone
[bytes appendBytes: &lBias length: 4];
[bytes appendBytes: standardName length: 64];
[bytes appendBytes: &stStandardDate length: 16];
[bytes appendBytes: &lStandardBias length: 4];
[bytes appendBytes: daylightName length: 64];
[bytes appendBytes: &stDaylightDate length: 16];
[bytes appendBytes: &lDaylightBias length: 4];
return [bytes activeSyncRepresentationInContext: context];
}
@end
+46
View File
@@ -0,0 +1,46 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ICALTODOACTIVESYNC_H__
#define __ICALTODOACTIVESYNC_H__
#import <NGCards/iCalToDo.h>
@class NSString;
@class WOContext;
@interface iCalToDo (ActiveSync)
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context;
- (void) takeActiveSyncValues: (NSDictionary *) theValues
inContext: (WOContext *) context;
@end
#endif
+192
View File
@@ -0,0 +1,192 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "iCalToDo+ActiveSync.h"
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSDate.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <Foundation/NSTimeZone.h>
#import <NGExtensions/NSString+misc.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <NGCards/iCalCalendar.h>
#import <NGCards/iCalDateTime.h>
#import <NGCards/iCalTimeZone.h>
#include "NSDate+ActiveSync.h"
#include "NSString+ActiveSync.h"
@implementation iCalToDo (ActiveSync)
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context
{
NSMutableString *s;
id o;
int v;
s = [NSMutableString string];
// Complete
o = [self completed];
[s appendFormat: @"<Complete xmlns=\"Tasks:\">%d</Complete>", (o ? 1 : 0)];
// DateCompleted
if (o)
[s appendFormat: @"<DateCompleted xmlns=\"Tasks:\">%@</DateCompleted>", [o activeSyncRepresentationInContext: context]];
// Start date
if ((o = [self startDate]))
{
[s appendFormat: @"<StartDate xmlns=\"Tasks:\">%@</StartDate>", [o activeSyncRepresentationInContext: context]];
[s appendFormat: @"<UTCStartDate xmlns=\"Tasks:\">%@</UTCStartDate>", [o activeSyncRepresentationInContext: context]];
}
// Due date
if ((o = [self due]))
{
[s appendFormat: @"<DueDate xmlns=\"Tasks:\">%@</DueDate>", [o activeSyncRepresentationInContext: context]];
[s appendFormat: @"<UTCDueDate xmlns=\"Tasks:\">%@</UTCDueDate>", [o activeSyncRepresentationInContext: context]];
}
// Importance
o = [self priority];
if ([o isEqualToString: @"9"])
v = 0;
else if ([o isEqualToString: @"1"])
v = 2;
else
v = 1;
[s appendFormat: @"<Importance xmlns=\"Tasks:\">%d</Importance>", v];
// Reminder - FIXME
[s appendFormat: @"<ReminderSet xmlns=\"Tasks:\">%d</ReminderSet>", 0];
// Sensitivity - FIXME
[s appendFormat: @"<Sensitivity xmlns=\"Tasks:\">%d</Sensitivity>", 0];
// Subject
o = [self summary];
if ([o length])
[s appendFormat: @"<Subject xmlns=\"Tasks:\">%@</Subject>", [[self summary] activeSyncRepresentationInContext: context]];
if ((o = [self comment]))
{
o = [o activeSyncRepresentationInContext: context];
[s appendString: @"<Body xmlns=\"AirSyncBase:\">"];
[s appendFormat: @"<Type>%d</Type>", 1];
[s appendFormat: @"<EstimatedDataSize>%d</EstimatedDataSize>", [o length]];
[s appendFormat: @"<Truncated>%d</Truncated>", 0];
[s appendFormat: @"<Data>%@</Data>", o];
[s appendString: @"</Body>"];
}
return s;
}
- (void) takeActiveSyncValues: (NSDictionary *) theValues
inContext: (WOContext *) context
{
NSTimeZone *userTimeZone;
iCalTimeZone *tz;
id o;
NSInteger tzOffset;
userTimeZone = [[[context activeUser] userDefaults] timeZone];
tz = [iCalTimeZone timeZoneForName: [userTimeZone name]];
[(iCalCalendar *) parent addTimeZone: tz];
// FIXME: merge with iCalEvent
if ((o = [theValues objectForKey: @"Subject"]))
[self setSummary: o];
// FIXME: merge with iCalEvent
if ((o = [[theValues objectForKey: @"Body"] objectForKey: @"Data"]))
[self setComment: o];
if ([[theValues objectForKey: @"Complete"] intValue] &&
((o = [theValues objectForKey: @"DateCompleted"])) )
{
iCalDateTime *completed;
o = [o calendarDate];
completed = (iCalDateTime *) [self uniqueChildWithTag: @"completed"];
//tzOffset = [[o timeZone] secondsFromGMTForDate: o];
//o = [o dateByAddingYears: 0 months: 0 days: 0
// hours: 0 minutes: 0
// seconds: -tzOffset];
[completed setDate: o];
[self setStatus: @"COMPLETED"];
}
if ((o = [theValues objectForKey: @"DueDate"]))
{
iCalDateTime *due;
o = [o calendarDate];
due = (iCalDateTime *) [self uniqueChildWithTag: @"due"];
[due setTimeZone: tz];
tzOffset = [userTimeZone secondsFromGMTForDate: o];
o = [o dateByAddingYears: 0 months: 0 days: 0
hours: 0 minutes: 0
seconds: tzOffset];
[due setDateTime: o];
}
// 2 == high, 1 == normal, 0 == low
if ((o = [theValues objectForKey: @"Importance"]))
{
if ([o intValue] == 2)
[self setPriority: @"1"];
else if ([o intValue] == 1)
[self setPriority: @"5"];
else
[self setPriority: @"9"];
}
if ((o = [theValues objectForKey: @"ReminderTime"]))
{
}
}
@end
+3
View File
@@ -0,0 +1,3 @@
{
requires = ( MAIN, Appointments, Contacts, Mailer );
}
+54 -1
View File
@@ -1,4 +1,57 @@
# use *:8843 for SSL
#
#
# Keep only one of those vhost definition, comment out the other one
#
#
# for https
# don't forget to add a Listen parameter for port 8843:
# Listen 8843
<VirtualHost *:8843>
ServerName YOUR.SERVER.NAME
SSLEngine on
SSLProtocol -ALL +SSLv3 +TLSv1
SSLHonorCipherOrder On
SSLCipherSuite HIGH:MEDIUM:!ADH:!aNULL:!eNULL:!NULL
SSLCertificateFile /path/to/your/cert/cert.pem
SSLCertificateChainFile /path/to/your/cert/cert-chain-file.pem
SSLCertificateKeyFile /path/to/your/key/file.key
RewriteEngine Off
ProxyRequests Off
SetEnv proxy-nokeepalive 1
ProxyPreserveHost On
ProxyPassInterpolateEnv On
ProxyPass /principals http://127.0.0.1:20000/SOGo/dav/ interpolate
ProxyPass /SOGo http://127.0.0.1:20000/SOGo interpolate
ProxyPass / http://127.0.0.1:20000/SOGo/dav/ interpolate
<Location />
<IfVersion < 2.4>
Order deny,allow
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</Location>
<Proxy http://127.0.0.1:20000>
RequestHeader set "x-webobjects-server-port" "8843"
RequestHeader set "x-webobjects-server-name" "CHANGETHIS:8843"
RequestHeader set "x-webobjects-server-url" "http://CHANGETHIS:8843"
RequestHeader set "x-webobjects-server-protocol" "HTTP/1.0"
AddDefaultCharset UTF-8
</Proxy>
ErrorLog /var/log/apache2/ab-error.log
CustomLog /var/log/apache2/ab-access.log combined
</VirtualHost>
# plain http
# Same here, don't forget to add a Listen parameter for port 8800:
# Listen 8800
<VirtualHost *:8800>
RewriteEngine Off
ProxyRequests Off
+22 -8
View File
@@ -2,13 +2,17 @@ Alias /SOGo.woa/WebServerResources/ \
/usr/lib/GNUstep/SOGo/WebServerResources/
Alias /SOGo/WebServerResources/ \
/usr/lib/GNUstep/SOGo/WebServerResources/
AliasMatch /SOGo/so/ControlPanel/Products/(.*)/Resources/(.*) \
/usr/lib/GNUstep/SOGo/$1.SOGo/Resources/$2
<Directory /usr/lib/GNUstep/SOGo/>
AllowOverride None
Order deny,allow
Allow from all
<IfVersion < 2.4>
Order deny,allow
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
# Explicitly allow caching of static content to avoid browser specific behavior.
# A resource's URL MUST change in order to have the client load the new version.
@@ -18,10 +22,6 @@ AliasMatch /SOGo/so/ControlPanel/Products/(.*)/Resources/(.*) \
</IfModule>
</Directory>
<LocationMatch "^/SOGo/so/ControlPanel/Products/.*UI/Resources/.*\.(jpg|png|gif|css|js)">
SetHandler default-handler
</LocationMatch>
## Uncomment the following to enable proxy-side authentication, you will then
## need to set the "SOGoTrustProxyAuthentication" SOGo user default to YES and
## adjust the "x-webobjects-remote-user" proxy header in the "Proxy" section
@@ -48,6 +48,14 @@ ProxyPreserveHost On
ProxyPass /SOGo http://127.0.0.1:20000/SOGo retry=0
# Enable to use Microsoft ActiveSync support
# Note that you MUST have many sogod workers to use ActiveSync.
# See the SOGo Installation and Configuration guide for more details.
#
#ProxyPass /Microsoft-Server-ActiveSync \
# http://127.0.0.1:20000/SOGo/Microsoft-Server-ActiveSync \
# retry=60 connectiontimeout=5 timeout=360
<Proxy http://127.0.0.1:20000/SOGo>
## adjust the following to your configuration
RequestHeader set "x-webobjects-server-port" "443"
@@ -66,3 +74,9 @@ ProxyPass /SOGo http://127.0.0.1:20000/SOGo retry=0
Allow from all
</Proxy>
# For Apple autoconfiguration
<IfModule rewrite_module>
RewriteEngine On
RewriteRule ^/.well-known/caldav/?$ /SOGo/dav [R=301]
</IfModule>
+10613
View File
File diff suppressed because it is too large. Load diff
+8
View File
@@ -0,0 +1,8 @@
all: $(patsubst %.asciidoc,%.pdf,$(wildcard *.asciidoc))
%.pdf : %.asciidoc
asciidoc -a docinfo1 -b docbook -d book -o $<.docbook $<
fop -c fonts/fop-config.xml -xsl docbook/xsl/sogo-fo.xsl -xml $<.docbook -pdf $@
clean:
rm *.asciidoc.docbook *.pdf
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,330 @@
Mobile Devices Configuration Guide
==================================
////
This file is part of the SOGo project.
See SOGo Mobile Devices Configuration-docinfo.xml for authors,
copyright and license information.
////
include::includes/global-attributes.asciidoc[]
About this Guide
----------------
This guide will walk you through the installation and configuration of
popular SyncML clients to be used with the SOGo solution.
This guide also include instructions for configuring Apple iPhone OS
devices (iPhone, iPod touch, and iPad).
The instructions are based on version {release_version} of SOGo.
The latest version of this guide is available at
http://www.sogo.nu/downloads/documentation.html.
Introduction
------------
SOGo is a free and modern scalable groupware server. It offers shared
calendars, address books, and emails through your favourite Web browser
and by using a native client such as Mozilla Thunderbird and Lightning.
SOGo is standard-compliant. It supports CalDAV, CardDAV, GroupDAV, iMIP
and iTIP and reuses existing IMAP, SMTP and database servers - making
the solution easy to deploy and interoperable with many applications.
SOGo features:
* Scalable architecture suitable for deployments from dozen to many
thousand users
* Rich Web-based interface that shares the look and feel, the features
and the data of Mozilla Thunderbird and Lightning
* Improved integration with Mozilla Thunderbird and Lighthing by using
the SOGo Connector and the SOGo Integrator
* Two-way synchronization support with any Microsoft ActiveSync-capable
device, or Outlook 2013
SOGo is developed by a community of developers located mainly in North
America and Europe. More information can be found on
http://www.sogo.nu/.
Installation
------------
This section will guide you through the installation of popular SyncML
clients on various devices.
Funambol SyncML Client
~~~~~~~~~~~~~~~~~~~~~~
The recommended SyncML client for BlackBerry, Apple iPhone (for
contacts), mobile devices based on Microsoft Windows Mobile Smartphone
or Windows Mobile PocketPC, is the one provided directly by Funambol,
which is free and open source.
For Microsoft Window Mobile, you must identify which kind of device you
have ("Smartphone" vs. "PocketPC").
Once you've identified what kind of device you have, download the
appropriate client from:
http://www.funambol.com/opensource/downloads.php
The version 8.5 GA or later is required. 
NextHaus SyncJe
~~~~~~~~~~~~~~~
For BlackBerry and Apple iPhone devices, you can also use the
SyncJe SyncML client from NextHaus (http://www.nexthaus.com/). This
client allows one to synchronize contacts, event and tasks with SOGo.
The version 2.43 or later is required. For BlackBerry 7XXX devices, the
required version is 2.25 but isn't officially supported. You can install
SyncJe on your BlackBerry device, over the air, by opening the following
link from your BlackBerry device:
http://www.nexthaus.com/bb/syncjebb.jad
This will download and install the application on your mobile device.
It's important to use the Web browser application and not the WAP
browser to perform this operation. Once installed, restart the device.
This procedure can also be used to update the SyncJe application. Note
that an update of SyncJe will not affect the state of previous
synchronizations. It's not necessary to perform a "slow sync" after an
update of SyncJe. 
Synthesis SyncML Client
~~~~~~~~~~~~~~~~~~~~~~~
The Synthesis (http://www.synthesis.ch/) company provides a SyncML
client for Palm OS-based devices.
"Over The Air" synchronization is possible, as well as synchronization
through a cradle. For the latter, you must install Softick PPP using the
Palm Desktop software. The version 3.01 or later is required and you can
download it from http://www.softick.com/ppp/. Once installed, the
desktop computer must be restarted.
Once completed, you must download the Synthesis client for Palm OS. The
version 3.0.2.9 or later is required. Either the standard or the
professional version can be used.
Once downloaded, uncompress the archive and install the `.prc` file on
your Palm OS-based device. After, you should see a "SyncML" icon on your
device.
Configuration
-------------
In this section, you'll learn how to configure the popular SyncML
clients in order to fully synchronize your mobile device with SOGo.
Instructions for Apple iPhone OS based devices are also included. Note
that those devices do not require a SyncML client for synchronizing
calendars.
Funambol SyncML Client
~~~~~~~~~~~~~~~~~~~~~~
Once the Funambol SyncML client is installed, start the application from
your mobile device to configure it using the following steps:
From the _Tools_ menu, choose _Options..._:
* Specify the _Location_. If your SOGo server is `sogo.domain.com`, the
location should be `http://sogo.domain.com/funambol/ds`.
* Specify your username and password
* Check the _Contacts_ check box and click on the _Details_ button.
The synchronization type is _two-way_ and the _Remote name_ is
`sogo-card`. The data format is vCard.
* Check the _Calendar_ check box and click on the _Details_ button. The
synchronization type is _two-way_ and the _Remote name_ is `sogo-cal`.
The data format is vCalendar.
* Check the _Tasks_ check box and click on the _Details_ button. The
synchronization type is _two-way_ and the _Remote name_ is
`sogo-todo`. The data format is SIF.
* Save the preferences.
To prevent the BlackBerry to automatically add a new event in the
calendar when an invitation is received by email (IMIP message) on the
BlackBerry device, you should delete the CICAL service from the Service
Book. To do so, proceed with the following steps:
From the _Options_ menu:
* Choose _Advanced Options_
* Choose _Service Book_
* Identify the line that mentions the email address of the BlackBerry
user followed by the `[CICAL]` string. For example, `user@domain.com
[CICAL]`.
* Delete this entry.
Once completed, you must restart the device by removing its battery for
a couple of seconds. If you ever want to reactivate the CICAL service,
follow those instructions:
http://support.appriver.com/KB/a205/how-to-resend-service-books-on-blackberry.aspx
Once complete, the client is ready for an initial synchronization.
Ideally, you should *delete* all data from the mobile device before the
initial synchronization. To do so:
* From the _Tools_ menu, choose _Recover..._
* Choose _Replace with data from server_
* Check the _Contacts_, _Calendar_ and _Tasks_ check boxes
Finally, click on the _Sync All_ button to proceed with the
synchronization.
NextHaus SyncJe
~~~~~~~~~~~~~~~
Once NextHaus SyncJe is installed, proceed with the following steps,
from your BlackBerry device, to configure it:
* Open the _SyncJe Client_
From the _Settings_ menu:
* Specify the _Server URL_. If your SOGo server is `sogo.domain.com`,
the URL should be `http://sogo.domain.com/funambol/ds`.
* Specify your user name and password
* Check the _Contacts_ check box and specify `sogo-card` as the
_Foldername_
* Check the _Calendar_ check box and specify `sogo-cal` as the
_Foldername_
* Check the _ToDo_ check box and specify `sogo-todo` as the _Foldername_
* Check the _Auto Sync_ check box if you wish to automatically
synchronize contacts, events and tasks at a predefined time interval
* Do *not* check the _Sync events between_ check box
* Check the _Skip saving attendees_ - this will prevent the BlackBerry
device from sending emails to meeting participants for events
downloaded from the SOGo server
* Check the _BIS_ check box (for _BlackBerry Internet Services_)
* Leave the other fields to the their default value
* Then choose _Save_ from the menu to save the preferences 
To prevent the BlackBerry to automatically add a new event in the
calendar when an invitation is received by email (IMIP message) on the
BlackBerry device, you should delete the CICAL service from the Service
Book. To do so, proceed with the following steps:
From the _Options_ menu:
* Choose _Advanced Options_
* Choose _Service Book_
* Identify the line that mentions the email address of the BlackBerry
user followed by the `[CICAL]` string. For example, `user@domain.com
[CICAL]`.
* Delete this entry
Once completed, you must restart the device by removing its battery for
a couple of seconds. If you ever want to reactivate the CICAL service,
follow those instructions:
http://support.appriver.com/KB/a205/how-to-resend-service-books-on-blackberry.aspx
Once done, you're now ready for your first synchronization.
Ideally, you must delete all data on the BlackBerry before proceeding
with the initial synchronization. To do so, proceed with the following
steps:
* Open the _SyncJe Client_
From the _Settings_ menu:
* Choose the _Clear databases_ option
* Respond _Yes_ to all questions. This will delete all contacts, events
and tasks from your BlackBerry device. 
* Go back in the previous menu
* Choose the _Force Slow Sync_ option
* Choose the _Start Sync_ option to start the synchronization. This
could take a few minutes if you have many contacts, events or tasks.
Subsequent synchronizations should be much faster. 
After the initial _Slow Sync_, you can simply chose the _Start Sync_
option if you do a manual synchronization to synchronize all changes. 
Synthesis SyncML Client
~~~~~~~~~~~~~~~~~~~~~~~
Once the Synthesis SyncML client is installed, proceed with the
following steps to configure it:
* Open the _Synthesis SyncML Standard Edition_ application
From the _Settings..._ menu:
* Specify the _Server URL_. If your SOGo server is `sogo.domain.com`,
the URL should be `http://sogo.domain.com/funambol/ds`.
* Specify your user name and password
* Check the _Contacts_, _Events_ and _Task_ check boxes
* Click on the _more..._ button
* For the _Contacts_, choose _reload device_ and specify `sogo-card` as
the _Server Path_.
* For the _Events_, choose _reload device_ and specify `sogo-cal` as
the _Server Path_. Do *not* check the _Only from..._ check box.
* For the _Tasks_, choose _reload device_ and specify `sogo-todo` as
the _Server Path_.
* Once completed, click on the _Done_ button
The _reload device_ value will *delete* all entries on the device during
the initial synchronization and obtain contacts, events and tasks from
the server. If you do not want to delete everything from the device,
please choose _normal_ instead of _reload device_.
Once ready, click on the _Start_ button to proceed with the initial
synchronization.
During the initial synchronization, the Palm device will ask you how to
connect to the desktop system. From the Palm device, choose _Windows
RAS_ without specifying an user name or a password. This will allow the
Palm device to establish a PPP connection between itself and Softick PPP
and then communicate using its TCP/IP stack to the Funambol server.
Apple iOS — Calendars
~~~~~~~~~~~~~~~~~~~~~
Starting from iOS 3, Apple has added CalDAV support to the calendar
application included in the iPhone/iPod/iPad.
To add a CalDAV account, follow those instructions:
* From the _Settings_ menu, choose _Mail, Contacts, Calendars_
* Choose _Add Account..._
* Choose _Other_
* Choose _Add CalDAV Account_
* Specify the _Server_, the URL should be
`http://sogo.domain.com/SOGo/dav/<username>`
On iOS 3.1.2 and later, you must also specify the range of events you
want to have. 
* From the _Settings_ menu, choose _Mail, Contacts, Calendars_
* From the _Sync_ menu, choose _All Events_
Note that other options (_Events 2 Weeks Back_, etc.) do not work right
now.
Apple iOS — Contacts
~~~~~~~~~~~~~~~~~~~~
If you want to synchronize contacts with your Apple mobile device, use
the native address book application with SOGo using the CardDAV
protocol. To configure the address book application so it works with
SOGo, create a new CardDAV account and specify your server name. In
the _Advanced Settings_, set the port to `8800`.
On iOS prior to version 4, you must install the Funambol client and
configure the `sogo-card` source.
include::includes/additional-info.asciidoc[]
include::includes/commercial-support.asciidoc[]
@@ -0,0 +1,358 @@
Mozilla Thunderbird Configuration Guide
=======================================
////
This file is part of the SOGo project.
See SOGo Mozilla Thunderbird Configuration Guide-docinfo.xml for
authors, copyright and license information.
////
include::includes/global-attributes.asciidoc[]
About this Guide
----------------
This guide will walk you through the installation and configuration of
Mozilla Thunderbird and its associated extensions so it can be used with
the SOGo solution.
The instructions are based on version {release_version} of SOGo.
The latest version of this guide is available
at http://www.sogo.nu/downloads/documentation.html.
Introduction
------------
SOGo is a free and modern scalable groupware server. It offers shared
calendars, address books, and emails through your favourite Web browser
and by using a native client such as Mozilla Thunderbird and Lightning.
SOGo is standard-compliant. It supports CalDAV, CardDAV, GroupDAV, iMIP
and iTIP and reuses existing IMAP, SMTP and database servers - making
the solution easy to deploy and interoperable with many applications.
SOGo features:
* Scalable architecture suitable for deployments from dozen to many
thousand users
* Rich Web-based interface that shares the look and feel, the features
and the data of Mozilla Thunderbird and Lightning
* Improved integration with Mozilla Thunderbird and Lightning by using
the SOGo Connector and the SOGo Integrator extensions
* Two-way synchronization support with any Microsoft ActiveSync-capable
device, or Outlook 2013
SOGo is developed by a community of developers located mainly in North
America and Europe. More information can be found on
http://www.sogo.nu/.
Installation
------------
This section will guide you through the installation of Thunderbird and
its associated extensions.
Mozilla Thunderbird
~~~~~~~~~~~~~~~~~~~
Mozilla Thunderbird is the official front end client of SOGo.
Mozilla Thunderbird version 2, 3.1, 10 ESR (Extended Support Release),
17 ESR, 24 and 31 are supported and it is recommended to use version 31 of
Thunderbird.
In order to download and install Mozilla Thunderbird, please visit:
https://www.mozilla.org/en-US/thunderbird/organizations/all-esr.html
Mozilla Lightning
~~~~~~~~~~~~~~~~~
When using version 24 or 31 of Thunderbird, you can use the latest version of
Mozilla Lightning. Use the Add-ons manager of Thunderbird or visit:
https://addons.mozilla.org/en-US/thunderbird/addon/lightning/
When using version 17 ESR of Thunderbird, you can use Mozilla Lightning
version 1.9.1. In order to download the extension, please visit:
https://addons.mozilla.org/en-US/thunderbird/addon/lightning/versions/1.9.1
For Thunderbird 2 and 3.1, you need the _Inverse Edition_of Mozilla
Lightning. It provides back ported features, bug fixes and security
fixes from the current development version of Mozilla Lightning. For
Thunderbird 2, it is based on release version 0.9 of Lightning. For
Thunderbird 3.1, it is based on 1.0b2.
In order to download and install Mozilla Lightning – Inverse Edition for
Thunderbird 2 or 3.1, please visit:
http://www.sogo.nu/downloads/frontends.html
SOGo Connector and SOGo Integrator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The SOGo Connector and Integrator extensions are provided to perfect the
integration of Mozilla Thunderbird 2, 3.1, 10 ESR, 17 ESR, 24 and 31 with
the SOGo groupware solution.
First of all, the SOGo Connector extension transforms Thunderbird into a
full DAV client for groupware servers such as SOGo, eGroupware or
Citadel. It does this by adding support for remote DAV address books and
by adding features to be used along with the Lightning calendar
extension.
Among supported features of the SOGo Connector extension, we have:
* Free / Busy URL field in the address book
* Free / Busy functionality through HTTP
* Event organizers
* Synchronization of the address book using GroupDAV
* CardDAV implementation for the address book
* Support for WebDAV ACL
On the other hand, the SOGo Integrator extension transforms Thunderbird
into a pure "heavy" client for SOGo. Whereas the SOGo Connector is meant
for portability (horizontal integration), the SOGo Integrator makes use
of the features and layout only available from SOGo (vertical
integration).
Among the supported features of the SOGo Integrator extension, we have :
* Remote administration of folder subscriptions
* Remote administration of folder access control lists (ACL)
* Automatic replication of your local and subscribed folders
* When correctly configured, it handles the propagation of updates to
chosen extensions from a local update server
* Automatic propagation of default settings
In order to download and install the SOGo Connector and Integrator
extensions, please visit:
http://www.sogo.nu/downloads/frontends.html
Prior to installing the SOGo Integrator extension, you should read the
following chapter – _SOGo Integrator Customization_.
SOGo Integrator Customization
-----------------------------
In this section, you'll learn how to customize the SOGo Integrator
extension so it can be used alongside your SOGo server.
Customization
~~~~~~~~~~~~~
The customization steps described here involves understanding of XML and
of text file edition. If you do not have those skills, it is recommended
that you don't try to use this extension.
There are actually two steps in the configuration of a working
environment for SOGo Integrator. First of all, the Integrator will use
the same user name used to connect to the first email server configured
in Thunderbird. It is a current limitation but it will fit nearly all
configurations out there.
For testing purpose, you are strongly recommended to create and
configure an additional user profile for Thunderbird. This is for two
reasons. The first is because of the limitation mentioned above. The
second is because the Integrator will synchronize your personal address
book onto the SOGo server and then remove it so that only your personal
address book on SOGo will be available. If you are not able to do that,
you may want to make a copy of that address book beforehand.
The second part requires editing one file in the extension file sub tree
to specify where the SOGo server is located. This is done by hand. In an
enterprise environment, this step is only required once per release
since the updates are expected to propagate automatically. 
Uncompress (using a ZIP or jar tool) the SOGo Integrator XPI and locate
the following file:
extensions.rdf
This file is used for locating the extension update server and the SOGo
server, which we consider to be the same for the moment. There is a line
starting with a "Seq" tag and with an attribute named "isi:updateURL".
Replace the host part of that url with the SOGo server you want to
connect to.
For example, one would replace:
<Seq about="http://inverse.ca/sogo-integrator/extensions" isi:updateURL="http://sogo-demo.inverse.ca/plugins/updates.php?plugin=%ITEM_ID%&amp;version=%ITEM_VERSION%&amp;platform=%PLATFORM%">
by:
<Seq about="http://inverse.ca/sogo-integrator/extensions" isi:updateURL="https://sogo.acme.com/plugins/updates.php?plugin=%ITEM_ID%&amp;version=%ITEM_VERSION%&amp;platform=%PLATFORM%">
if the SOGo server is accessible from the following URL:
https://sogo.acme.com/SOGo
Note that if you changed the `x-webobjects-server-url` configuration
setting from your HTTP server configuration file for SOGo, the
value *must* match the one you specify in `isi:updateURL` – even the
port number.
Moreover, you *must* change the value of the
`sogo-integrator.autocomplete.server.urlid` preference from
`defaults/preferences/site.js` to match the identifier of your
_SOGoUserSources_. This source will be used by Thunderbird for
autocompletion.
Once you're done modifying the configuration file, save your changes and
reconstruct the XPI file. 
Now start Thunderbird and install your newly modified extension.
SOGo Update Server
------------------
In this section, you will learn how to install and configure the SOGo
Update Server.
The SOGo Update Server can be used to automatically install or uninstall
Mozilla Thunderbird extensions, push user settings and more – all from a
central place managed by system administrators.
Installation
~~~~~~~~~~~~
Installation is relatively straightforward. You need to make
the `updates.php` script available through your HTTP server at the URL
you've specified from the `extensions.rdf` file. The `updates.php`
script can be found in the SOGo sources, under the `Scripts` directory.
The `updateLink` section of the XML payload returned to sogo-integrator
is built dynamically using the `SCRIPT_URI` variable, which is only
available when running with mod_rewrite. It should work out of the box
as long as the script is placed in the same directory as the xpi files.
If it is not the case, then the link should be adjusted to fit the
actual file layout:
<em:updateLink><?php echo dirname(getenv('SCRIPT_URI')) . '/relative/path/to/' . $plugin["filename"] ?></em:updateLink>
An http request similar to the following can be used to make sure that
the generated link is correct:
http://sogo.host/path/to/updates.php?plugin=sogo-integrator@inverse.ca&version=0.00
Please refer to your HTTP server documentation for the installation and
configuration of PHP.
Configuration
~~~~~~~~~~~~~
To configure the SOGo update server, you need to modify the
`updates.php` script directly.
Adding an extension to be pushed automatically by the update server
require you to modify the `$plugins` array from updates.php and also
adjust accordingly SOGo Integrator's `extensions.rdf` file.
For example, to automatically install SOGo Connector, SOGo Integrator
and Lightning, you would have:
----
$plugins
= array( "sogo-connector@inverse.ca"
=> array( "application" => "thunderbird",
"version" => "31.0.0",
"filename" => "sogo-connector-31.0.0.xpi" ),
"sogo-integrator@inverse.ca"
=> array( "application" => "thunderbird",
"version" => "31.0.0",
"filename" => "sogo-integrator-31.0.0-sogo-demo.xpi" ),
"{e2fda1a4-762b-4020-b5ad-a41df1933103}"
=> array( "application" => "thunderbird",
"version" => "3.3.1",
"filename" => "lightning.xpi" ));
----
The syntax is:
----
"<extension ID>"
=> array( "application" => "thunderbird",
"version" => "<exact version found in the extension's install.rdf file>",
"filename" => "<exact filename on the filesystem>" )
----
The path of the filename, specified in the `filename` parameter, is
relative to the location of the `updates.php` script. For extensions
that are dependant on the architecture and operating system (Microsoft
Windows, Apple Mac OS X, etc.), they can be placed in subdirectories
relative again to the `updates.php` script (but the filename must be
identical in all subdirectories). For exemple, for Mozilla Lightning, we
could have:
----
Darwin_x86-gcc3/lightning.xpi
Linux_x86-gcc3/lightning.xpi
Linux_x86_64-gcc3/lightning.xpi
WINNT_x86-msvc/lightning.xpi
----
If you eventually want to disable an extension, that is, without
removing it from your users' computers, you can specify `disabled` as
the version number.
Next is to modify the `extensions.rdf` file. Again, to automatically
install SOGo Connector, SOGo Integrator and Lightning, you would have:
----
<li>
<Description
em:id="{e2fda1a4-762b-4020-b5ad-a41df1933103}"
em:name="Lightning"/>
</li>
<li>
<Description
em:id="sogo-integrator@inverse.ca"
em:name="SOGo Integrator"/>
</li>
<li>
<Description
em:id="sogo-connector@inverse.ca"
em:name="SOGo Connector"/>
</li>
----
Using SOGo Integrator, you can also push user-settings for any part of
Thunderbird or its extensions. There are two kind of user-settings
push:
* Settings that are pushed during the initial configuration of
Thunderbird
* Settings that are pushed upon every restart (ie., forced) of
Thunderbird
Settings that pushed are pushed during initial configuration are
controlled by the `./defaults/preferences/site.js` file from SOGo
Integrator. Here is an example:
----
pref("calendar.alarms.showmissed", false);
pref("calendar.caldav.sched.enabled", true);
----
Preferences that are forced upon every restart of Thunderbird are
controlled from the `./chrome/content/general/custom-preferences.js`
configuration file.
Here is an example:
----
force_int_pref("changequote.replyformat.format", 0);
force_bool_pref("changequote.headers.withcc", true);
force_char_pref(“foo.bar”, “zot”);
----
include::includes/additional-info.asciidoc[]
include::includes/commercial-support.asciidoc[]
@@ -0,0 +1,758 @@
Native Microsoft Outlook Configuration Guide
============================================
////
This file is part of the SOGo project.
See SOGo Native Microsoft Outlook Configuration-docinfo.xml for
authors, copyright and license information.
////
include::includes/global-attributes.asciidoc[]
About this Guide
----------------
This guide will walk you through the installation and configuration of
the native Microsoft Outlook compatibility layer SOGo offers.
Prior going over this guide, you should have a working SOGo
installation. Please refer to the _SOGo Installation and Configuration
Guide_ for more information on installing and configuring SOGo.
This guide also includes instructions for configuring Microsoft Outlook
with SOGo.
The instructions are based on version {release_version} of SOGo.
The latest version of this guide is available
at http://www.sogo.nu/downloads/documentation.html.
Introduction
------------
SOGo is a free and modern scalable groupware server. It offers shared
calendars, address books, and emails through your favourite Web browser
and by using a native client such as Mozilla Thunderbird and Lightning.
SOGo is standard-compliant. It supports CalDAV, CardDAV, GroupDAV, iMIP
and iTIP and reuses existing IMAP, SMTP and database servers — making
the solution easy to deploy and interoperable with many applications.
SOGo features:
* Scalable architecture suitable for deployments from dozen to many
thousand users
* Rich Web-based interface that shares the look and feel, the features
and the data of Mozilla Thunderbird and Lightning
* Improved integration with Mozilla Thunderbird and Lightning by using
the SOGo Connector and the SOGo Integrator
* Native compatibility for Microsoft Outlook 2003, 2007, 2010, and 2013
* Two-way synchronization support with any Microsoft ActiveSync-capable
device, and Outlook 2013
SOGo is developed by a community of developers located mainly in North
America and Europe. More information can be found
on http://www.sogo.nu/.
Architecture
------------
The following diagram demonstrates the architecture of the native
Outlook compatibility layer of SOGo.
image::images/openchange.png[]
With Samba 4 and OpenChange, Microsoft Outlook clients can communicate
natively with SOGo using the Microsoft Exchange protocol, without
requiring costly and hard-to-maintain third-party MAPI connectors for
Microsoft Outlook.
Requirements
------------
Organizations generally have solutions to authenticate users such as
LDAP servers or Microsoft Active Directory servers.
The solution being used will influence how users are provisioned in
Samba 4, a key component for native Outlook compatibility in SOGo.
LDAP Server
~~~~~~~~~~~
If your organization uses a LDAP server such OpenLDAP, Novell
eDirectory, Apache Directory or any other solution, you must use
Samba 4's internal directory server and synchronize the data between
both.
Synchronization scripts are not provided and unless you have clear-text
passwords of your existing users, they will have to be changed during
your initial synchronization so that your LDAP's server passwords are
identical to the ones from Samba 4.
Any modifications to your existing LDAP server (password change, user
addition or deletion, etc.) will have to be replicated to Samba 4's
internal directory server.
Note that if you install Samba 4 on a server that is already running a
LDAP service, you will have to change to TCP port on which your LDAP
server listens to. Samba 4 will use the TCP port 389 and it can't be
changed.
For example, with OpenLDAP, you can use the `-h` parameter for `slapd`
to make it listen on an other TCP port.
Microsoft Active Directory
~~~~~~~~~~~~~~~~~~~~~~~~~~
If your organization uses Microsoft Active Directory, Samba 4 will need
to be joined to your Active Directory domain, as a DC.
Samba 4 will be able to reuse all the information contained in Microsoft
Active Directory and no synchronization process needs to be put in place
as information will get replicated to Samba 4 automatically.
For more information on joining Samba 4 to an existing Microsoft Active
Directory domain, please refer to the Samba 4 documentation available at
the following URL:
http://wiki.samba.org/index.php/Samba4
More specifically, have a look at the `samba-tool domain join` command.
Note that joining Samba 4 to your Active Directory domain as a member
will currently not work. An authentication bug is present in Samba 4
which then prevents all Outlook users to successfully authenticate
through Samba 4. This issue has been reported to the Samba team and is
being worked on.
Other or No Solution
~~~~~~~~~~~~~~~~~~~~
If your organization neither uses a LDAP server or Microsoft Active
Directory, you can start using Samba 4 as your directory server.
Samba 4's directory can be queried over LDAP just like Microsoft Active
Directory and can also serve as a domain controller for Windows-based
environments.
For example, SOGo can very well use Samba 4's built-in directory server
to authenticate users. A SOGoUserSources entry to achieve this wold look
like this:
----
su – sogo
defaults write sogod SOGoUserSources '(
{
CNFieldName = displayName;
IDFieldName = cn;
UIDFieldName = sAMAccountName;
baseDN = "cn=Users,dc=example,dc=com";
bindDN = "cn=Administrator,cn=Users,dc=example,dc=com";
bindFields = (
sAMAccountName
);
bindPassword = "%1OpenChange";
canAuthenticate = YES;
displayName = "Shared Addresses";
hostname = "127.0.0.1";
id = samba;
isAddressBook = YES;
port = 389;
}
)'
----
Please refer to the _SOGo Installation and Configuration Guide_ for more
information regarding `SOGoUserSources`.
IMAP Server and Trust
~~~~~~~~~~~~~~~~~~~~~
An IMAP server supporting the ACL, UIDPLUS and QRESYNC IMAP extensions
is required, such as Cyrus IMAP version 2.4 or later, or Dovecot version
2.1 or later. If your current IMAP server does not support these
extensions, you can use Dovecot's proxying capabilities. The follow
configuration example makes Dovecot proxy all IMAP request to an
existing server:
----
auth_mechanisms = plain login
imapc_host = inverse.ca
imapc_port = 993
imapc_ssl = imaps
imapc_ssl_verify = no
mail_gid = imapproxy
mail_home = /home/imapproxy/%u
mail_location = imapc:~/imapc
mail_uid = imapproxy
passdb {
args = host=inverse.ca ssl=imaps port=993 ssl_ca_dir=/etc/pki/tls/certs
default_fields = userdb_imapc_user=%u userdb_imapc_password=%w
driver = imap
}
protocols = imap
ssl = no
userdb {
driver = prefetch
}
----
SOGo would then be configured to use Dovecot's proxy as the IMAP server.
Moreover, the authentication mode in use by Windows with Samba and
Exchange servers prevent the backend from knowing the real password
being used by the user. This implies that the IMAP server must accept
any passwords from the host on which Samba is running.
To accomplish this with Cyrus IMAP Server, set `sasl_pwcheck_method`
to `alwaystrue` in `/etc/imapd.conf`. You should restrain this to
an `imapd` instance dedicated to SOGo.
For Dovecot, use an authentication source similar to:
----
passdb {
driver = static
args = nopassword=y allow_nets=127.0.0.1/32
}
----
You should also make sure that you restrain this only to the SOGo
processes.
For any other IMAP server, refer to the product's documentation. If such
capability is not offered, you can alternatively define the cleartext
password for each user. Please refer to the _Adding Users_ section from
this document.
Installation
------------
This section will guide you through the installation of the native
Microsoft Outlook compatibility layer SOGo offers.
Red Hat Enterprise Linux v6 x86_64
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you are using Red Hat Enterprise Linux version 6 x86_64, packages
for Samba 4, OpenChange and SOGo and the SOGo OpenChange backend are
available from SOGo's web site. Please follow the instructions from
http://www.sogo.nu/english/downloads/backend_nightly.html.
In order to satisfy certain dependencies, you should also add the EPEL
source corresponding to your distribution and architecture. More
information on this is available here:
http://fedoraproject.org/wiki/EPEL – or more specifically,
http://fedoraproject.org/wiki/EPEL/FAQ#How_can_I_install_the_packages_from_the_EPEL_software_repository.3F.
Once ready, install the OpenChange packages on top of an existing SOGo
installation:
----
yum clean all && yum makecache
yum install samba \
openchange \
sogo-openchange-backend \
openchange-ocsmanager \
openchange-rpcproxy \
mysql-server \
MySQL-python
----
Once the packages are installed, refer to the _Configuration_ chapter
from this guide.
[NOTE]
Samba4/OpenChange are not available for now on CentOS 5 i386/x86_64,
CentOS 6 i386 and CentOS 7.
Debian 7.0 (Wheezy) and Ubuntu 12.04 (Precise Pangolin)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SOGo, OpenChange and the SOGo OpenChange backend are now
available from SOGo's web site. Please follow the instructions from
http://www.sogo.nu/english/downloads/backend.html to setup your
apt sources.
For Samba 4, you need to use the _wheezy-backports_ repository. To do so, create
`/etc/apt/sources.list.d/backports.list`:
deb http://http.debian.net/debian wheezy-backports main
On Ubuntu 12.04, you will also have to add the Wheezy sources:
deb http://ftp.us.debian.org/debian wheezy main
deb http://security.debian.org/ wheezy/updates main
Then install Samba 4 on top of an existing SOGo
installation:
----
apt-get update
apt-get -t wheezy-backports install samba samba-dev
----
Once completed, install the packages related to OpenChange and the SOGo
provider:
----
apt-get install openchangeserver \
sogo-openchange \
openchangeproxy \
python-ocsmanager \
mysql-server \
python-mysqldb
----
Once the packages are installed, refer to the _Configuration_ chapter
from this guide.
[NOTE]
On Ubuntu 12.04, the Samba init scripts need to be modified to
disable the upstart check. For more details, refer to:
https://wiki.samba.org/index.php/Samba4/InitScript
Ubuntu 14.04 (Trusty Tahr)
~~~~~~~~~~~~~~~~~~~~~~~~~~
For Ubuntu 14.04, you must not use the Debian Wheezy backports.
Please follow the instructions from
http://www.sogo.nu/english/downloads/backend.html to setup your
apt sources.
Then install Samba 4 on top of an existing SOGo
installation:
----
apt-get update
apt-get install samba samba-dev
----
Once completed, install the packages related to OpenChange and the SOGo
provider:
----
apt-get install openchangeserver \
sogo-openchange \
openchangeproxy \
python-ocsmanager \
mysql-server \
python-mysqldb
----
Once the packages are installed, refer to the _Configuration_ chapter
from this guide.
Configuration
-------------
In this section, you'll learn how to configure the native Microsoft
Outlook compatibility layer that SOGo offers.
SOGo Configuration
~~~~~~~~~~~~~~~~~~
First thing to do is to configure SOGo to use your current services,
which are your IMAP, SMTP and SQL database servers. The configuration
instructions for this are available in the SOGo Installation and
Configuration Guide available from http://www.sogo.nu/.
Please refer to that documentation before continuing with the
instructions included in this guide.
Samba 4 Configuration
~~~~~~~~~~~~~~~~~~~~~
Run the following commands as root: 
----
samba-tool domain provision --realm=example.com \
--domain=OPENCHANGE \
--adminpass='%1OpenChange' \
--server-role='domain controller'
samba-tool user setexpiry administrator --noexpiry
----
You might consider changing the realm and domain used, to suit your
enviroment.
You might also have to
remove `/etc/samba/smb.conf` prior running this command.
Add the following parameters to the `[global]` section of the
`/etc/samba/smb.conf` configuration file:
----
### Configuration required by OpenChange server ###
dcerpc endpoint servers = epmapper, mapiproxy, dnsserver
dcerpc_mapiproxy:server = true
dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr
### Configuration required by OpenChange server ###
----
Your Samba 4 configuration file should look like this:
----
# Global parameters
[global]
server role = active directory domain controller
workgroup = EXAMPLE
realm = example.com
netbios name = sogo
passdb backend = samba4
### Configuration required by OpenChange server ###
dcerpc endpoint servers = +epmapper, +mapiproxy
dcerpc_mapiproxy:server = true
dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr
### Configuration required by OpenChange server ###
[netlogon]
path = /var/lib/samba/sysvol/example.com/scripts
read only = No
[sysvol]
path = /var/lib/samba/sysvol
read only = No
----
OpenChange Configuration
~~~~~~~~~~~~~~~~~~~~~~~~
OpenChange 2.2 stores its metadata in MySQL so you need to have it installed.
First, create the OpenChange MySQL user:
----
$ mysql -u root -p
mysql> CREATE USER 'openchange-user'@'localhost' IDENTIFIED BY 'openchange$123';
mysql> GRANT ALL PRIVILEGES ON `openchange`.* TO 'openchange-user'@'localhost' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
----
The Samba AD schema needs to be filled with additional object
definitions by running the following commands: 
----
openchange_provision --standalone
NOTE: This operation can take several minutes
[+] Step 1: Register Exchange OIDs
[+] Step 2: Add Exchange attributes to Samba schema
[+] Step 3: Add Exchange auxiliary classes to Samba schema
[+] Step 4: Add Exchange objectCategory to Samba schema
[+] Step 5: Add Exchange containers to Samba schema
[+] Step 6: Add Exchange *sub* containers to Samba schema
[+] Step 7: Add Exchange CfgProtocol subcontainers to Samba schema
[+] Step 8: Add Exchange mailGateway subcontainers to Samba schema
[+] Step 9: Add Exchange classes to Samba schema
[+] Step 10: Add possSuperior attributes to Exchange classes
[+] Step 11: Extend existing Samba classes and attributes
[+] Step 12: Generic Exchange configuration objects
[+] Step 13: Finalize generic Exchange configuration objects
[SUCCESS] Done!
[+] Step 1: Exchange Samba registration
[SUCCESS] Done!
[+] Step 1: Register Exchange Samba as the main server
[SUCCESS] Done!
----
Create the OpenChange database: 
----
openchange_provision --openchangedb --openchangedb-uri 'mysql://openchange-user:openchange$123@localhost/openchange'
Setting up openchange db
[+] Public Folders
===================
* Public Folder Root : 0x0100000000000001 (72057594037927937)
* IPM_SUBTREE : 0x0200000000000001 (144115188075855873)
* NON_IPM_SUBTREE : 0x0300000000000001 (216172782113783809)
* EFORMS REGISTRY : 0x0400000000000001 (288230376151711745)
* OFFLINE ADDRESS BOOK : 0x0500000000000001 (360287970189639681)
* /o=First Organization/cn=addrlists/cn=oabs/cn=Default Offline Address Book: 0x0600000000000001 (432345564227567617)
* SCHEDULE+ FREE BUSY : 0x0700000000000001 (504403158265495553)
* EX:/o=first organization/ou=first administrative group: 0x0800000000000001 (576460752303423489)
* Events Root : 0x0900000000000001 (648518346341351425)
----
Finally, modify `/etc/samba/smb.conf` to specify OpenChange connection information
for its indexing database. Add the following at the end of the `[global]` section:
----
mapistore:namedproperties = mysql
namedproperties:mysql_user = openchange-user
namedproperties:mysql_pass = openchange$123
namedproperties:mysql_host = localhost
namedproperties:mysql_db = openchange
mapistore:indexing_backend = mysql://openchange-user:openchange$123@localhost/openchange
mapiproxy:openchangedb = mysql://openchange-user:openchange$123@localhost/openchange
----
On RHEL, make sure SELinux is disabled:
setenforce 0
Next, you can start Samba using the usual command:
/etc/init.d/samba start
On upstart-based distributions, use:
start samba-ad-dc
You can also launch the OpenChange web services:
/etc/init.d/openchange-ocsmanager start
Apache Configuration for Web Services
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The OpenChange web services consist of two components:
1. *OCS Manager* which is used for autodiscovery and freebusy lookups on
Outlook 2007 and 2010. This service runs in its own application server
which listens on `127.0.0.1:5000` by default. Apache needs to be
configured to forward certain requests to it to make it accessible from
the outside.
Note that this service *MUST* be accessible over*HTTPS*, otherwise Outlook
won't use it.
2. *RPC Proxy* which is used for RPC over HTTP ("Outlook Anywhere").
This service runs as a WSGI application under apache (mod_wsgi).
While HTTPS is not required to access this service, it is strongly
recommended.
On RHEL-based distributions, the apache configuration required by these
services can be found in `/etc/httpd/conf.d/ocsmanager.conf` and
`/etc/httpd/conf.d/rpcproxy.conf`.
For Debian-based distributions, these files can be found
in `/etc/apache2/conf.d/`.
The configuration requires three Apache modules:  _mod_proxy_,
_mod_proxy_http_ and _mod_wsgi_. These are usually already installed but
might need to be activated on Debian-based installations:
a2enmod proxy proxy_http wsgi
On RHEL-based distributions, make sure the `LoadModule` directive is
uncommented in `/etc/httpd/conf.d/wsgi.conf` (or
`python26-mod_wsgi.conf` on RHELv5).
The _reqtimeout_ apache module is known to cause problems when using the
default configuration shipped with Debian-based systems. On such
distributions, apache will close (HTTP/1.1 500) any HTTP request for
which the HTTP body hasn't arrived in 10 seconds.
While this is arguably good practice with regular HTTP, it will disrupt
the RPC over HTTP protocol implemented by RPC Proxy: Outlook will
continuously disconnect and reconnect leading to suboptimal performance.
To avoid this problem, use a much higher timeout or disable the module:
a2dismod reqtimeout
You should now restart the Apache service and make sure it will start on
boot. On RHEL-based distributions, do:
chkconfig httpd on && /etc/init.d/httpd restart
On Debian-based distributions, do:
update-rc.d apache2 defaults && /etc/init.d/apache2 restart
[NOTE]
Debian-based distributions are not supported anymore for
OCSManager/rpcproxy. Support will soon resume.
Name Service Configuration for Web Services
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The autodiscovery service must be made accessible in order to advertise
the web services provided by OpenChange. This can be done in two ways.
1. The first is to associate the FQDN `autodiscover.example.com.` with
the machine that hosts Samba 4 / OpenChange, by adding a `CNAME` entry
in your DNS configuration. Note that, instead or changing your DNS
server configuration, you can simply add a similar entry to the _hosts_
file of the Windows machine from where you'll run Outlook, which is
handy for testing purposes.
2. The second option is to add a `SRV` entry to your DNS configuration
where the `_service` value would be `Autodiscover` and the `_protocol`
would be `_tcp`.
For example:
_autodiscover._tcp.example.com. IN SRV 0 0 443 sogo.example.com.
Again, the autodiscovery service must be accessible over HTTPS.
Adding Users
------------
Users that wish to connect natively to SOGo must be provisioned in
Samba 4 and in OpenChange – even if they already exist in your current
LDAP or Microsoft Active Directory server.
To add a user, execute the following commands: 
----
# add user to samba
samba-tool domain passwordsettings set --complexity=off
samba-tool domain passwordsettings set --min-pwd-length=1
samba-tool user add <username>
samba-tool user setexpiry <username> --noexpiry
# create user in openchange
openchange_newuser --create <username>
----
If you don't have a trust between your IMAP server and SOGo, you must at
this point set the cleartext password of the newly created user in
`/var/lib/samba/private/mapistore/<username/password`.
This per-user file contains the cleartext password of the user as a
UTF-8 string, on a single line. This password will be used to
authenticate SOGo/OpenChange storage provider to your IMAP server.
Microsoft Outlook Configuration
-------------------------------
To connect Microsoft Outlook, you can either use the IP address of the
server or its DNS name. If you prefer using the DNS name, add an entry
like the following to the `c:\windows\system32\drivers\etc\hosts` file
in order to associate the IP address with the right DNS names:
192.168.1.1 sogo.example.com autodiscover.example.com
Next, you must configure Microsoft Outlook.
* Open the Control Panel => Mail => Email Accounts.
* Select _Add a new e-mail account_
* Choose _Microsoft Exchange Server_
* Fill the required information. Enter the DNS name or the IP address of
your SOGo server in the _Microsoft Exchange Server_ field
* Leave the _Use Cached Exchange Mode_ checkbox enabled
* Enter your username in the _User Name_ field
* Click on _More Settings_ and ignore the warning, if any, about
Exchange being offline by clicking on Cancel
* From the Security tab, enable Always prompt for user name and password
* From the _Connection_ tab, enable _"Outlook Anywhere"_ if you plan to
use Outlook outside of your LAN. Moreover, click on the _Exchange Proxy
Settings..._ button to enable it for slow and fast networks. Specify
also the host, which should be the same value you specified in the
Microsoft Exchange Server field.
* Finally, click on Check Name and confirm your username and password
Start Microsoft Outlook and enter your username and password. It will
start to synchronize your mailbox. This could take a long time if you
have many emails, events, tasks and contacts. Once this step is
completed, check the autodiscovery service with Outlook 2007 or 2010 by
simultaneously holding the CTRL key on your keyboard and right-clicking
on the Outlook icon in the notification toolbar. A special entry named
"Test E-mail AutoConfiguration..." will appear and will enable you to
check the service.
Known Issues or Limitations
---------------------------
* Make sure you periodically backup all your data regarding SOGo.
* Make sure you have no firewalls activated between your Microsoft
Outlook clients and the SOGo server with Native Outlook Compatibility
module. If you do, use "Outlook Anywhere" to connect Outlook to
SOGo/OpenChange.
Current Limitations
~~~~~~~~~~~~~~~~~~~
The current version of the Native Microsoft Outlook compatibility layer
has some limitations.
Those limitations will be overcome in the upcoming releases. If you are
interested in having those limitations fixed more rapidly, please
contact Inverse by sending an email to support@inverse.ca.
General
^^^^^^^
* If you can't see any email's content with Microsoft Outlook 2007,
install the latest Service Pack available from Microsoft's website for
this specific version. Microsoft Outlook 2007 (12.0.6423.100) SP2 MSO
(12.0.6425.1000) is known to work.
* When you create a new Microsoft Outlook profile, not all folders might
be synchronized during the first start. Simply select the appropriate
folder and click "Send and Receive". Synchronizing a folder may take
some time. For example, a folder with 1000 email messages might take
around 5 minutes based on the underlying hardware.
* Errors when synchronizing the "Offline Address Book" are normal and
can be ignored for now. This feature is currently not supported.
* If you face strange issues from Microsoft Outlook, you might want to
remove any data associated with the user from the SOGo server and
recreate a Microsoft Outlook profile.
To remove any data associated to a user, use
the `openchange_user_cleanup` script distributed with SOGo. The script
can be found in `/usr/share/doc/sogo/` (`/usr/share/sogo-VERSION/` on
RHEL).
To reset a user, run the script as root:
`python openchange_user_cleanup username`. See the usage output for additional options.
* The "Out of Office Assistant" will not currently work. This feature
has not been implemented.
* Creating folders below INBOX (when not normally permitted by the IMAP
server), below the Personal Calendar or Personal Address Book will work
in Outlook cached mode but the server-side operation will fail and these
folders will never be created. Potentially data loss can occur if the
Outlook profile is destroyed. If you wan to create additional top-level
mail folders, calendars or address books, open Outlook's folder list,
select the top level node (usually, "email@example.com") and choose "New
Folder..." from the contextual menu. Choose the relevant item types.
Mail
^^^^
* Sharing mail folders is not supported.
* To avoid possibly lossy conversion from RTF to HTML, Outlook should be
configured to send all mails as HTML (or plaintext) instead of _Outlook
Rich Text Format_.
Calendar
^^^^^^^^
* Labels will not work.
* It might be impossible to view event details from a shared calendar.
This issue is being worked on.
Tasks
^^^^^
* Tasks with start/due dates created from Outlook might not appear
correctly in SOGo due to a timezone issue.
* Reminders are not yet supported.
* Assigning tasks will not work.
Contacts
^^^^^^^^
* Categories will not work.
* Distribution lists will not work.
* Under Microsoft Outlook 2010, the special folder "Suggested Contacts"
will not work.
* The "Offline Address Book" will not work. This feature is not yet
supported.
Notes
^^^^^
* Notes are not synchronized in any ways with SOGo. The current version
of SOGo lacks support for notes.
If you notice anything else, please send contact Inverse by sending an
email to support@inverse.ca.
include::includes/additional-info.asciidoc[]
include::includes/commercial-support.asciidoc[]
Binary file not shown.

Before

Width:  |  Height:  |  Size: 433 KiB

+16
View File
@@ -0,0 +1,16 @@
#
# fop fix to build our documentation on CentOS 6
#
# Inverse inc. <info@inverse.ca>
#
--- /usr/bin/fop.orig 2012-01-17 21:25:50.000000000 -0500
+++ /usr/bin/fop 2012-01-17 21:26:04.000000000 -0500
@@ -26,7 +26,7 @@
# Set parameters
set_jvm
set_classpath commons-io batik-all avalon-framework xmlgraphics-commons \
- commons-logging fop
+ commons-logging fop xalan-j2
set_flags $BASE_FLAGS
set_options $BASE_OPTIONS
@@ -0,0 +1,17 @@
#
# xmlgraphics-fop fix to build our documentation on CentOS 5
# taken from https://build.opensuse.org/request/show/68994
#
# Inverse inc. <info@inverse.ca>
#
--- /usr/bin/xmlgraphics-fop.orig 2012-01-17 18:42:08.000000000 -0500
+++ /usr/bin/xmlgraphics-fop 2012-01-17 18:42:18.000000000 -0500
@@ -24,7 +24,7 @@
# Rest of the configuration
MAIN_CLASS=org.apache.fop.cli.Main
-BASE_JARS="xmlgraphics-fop xmlgraphics-batik/util xml-commons-jaxp-1.3-apis excalibur/avalon-framework-api xerces-j2 xalan-j2 xalan-j2-serializer"
+BASE_JARS="xmlgraphics-fop batik-all xml-commons-jaxp-1.3-apis excalibur/avalon-framework-impl excalibur/avalon-framework-api xerces-j2 xalan-j2 xalan-j2-serializer"
# Set parameters
set_jvm
@@ -0,0 +1,107 @@
<?xml version='1.0'?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
<!-- ********************************************************************
Header / Footer customizations
This file is part of the SOGo project.
Authors:
- Inverse inc. <info@inverse.ca>
Copyright (C) 2011-2014 Inverse inc.
License: GFDL 1.2 or later. http://www.gnu.org/licenses/fdl.html
******************************************************************** -->
<!--
Here we are re-defining docbook-xsl/fo/pagesetup.xsl to fit our needs.
- top: chapter number on the left
- bottom: copyright, chapter name, page
-->
<xsl:param name="header.rule" select="0"/>
<xsl:template name="header.content">
<xsl:param name="pageclass" select="''"/>
<xsl:param name="sequence" select="''"/>
<xsl:param name="position" select="''"/>
<xsl:param name="gentext-key" select="''"/>
<fo:block>
<!-- sequence can be odd, even, first, blank -->
<!-- position can be left, center, right -->
<xsl:choose>
<xsl:when test="$sequence = 'blank'">
<!-- nothing -->
</xsl:when>
<xsl:when test="($sequence='first' or $sequence='odd' or $sequence='even') and $position='left'">
<xsl:if test="$pageclass != 'titlepage' and $pageclass != 'lot'">
<xsl:call-template name="gentext">
<xsl:with-param name="key" select="'chapter'"/>
</xsl:call-template>
<xsl:call-template name="gentext.space"/>
<xsl:number count="chapter" from="book" level="any"/>
</xsl:if>
</xsl:when>
<!-- draft -->
<xsl:when test="$position='right'">
<xsl:call-template name="draft.text"/>
</xsl:when>
<xsl:otherwise>
<!-- nop -->
</xsl:otherwise>
</xsl:choose>
</fo:block>
</xsl:template>
<xsl:param name="footer.rule" select="0"/>
<xsl:template name="footer.content">
<xsl:param name="pageclass" select="''"/>
<xsl:param name="sequence" select="''"/>
<xsl:param name="position" select="''"/>
<xsl:param name="gentext-key" select="''"/>
<fo:block>
<!-- pageclass can be front, body, back -->
<!-- sequence can be odd, even, first, blank -->
<!-- position can be left, center, right -->
<xsl:choose>
<xsl:when test="$pageclass = 'titlepage'">
<!-- nop; no footer on title pages -->
</xsl:when>
<xsl:when test="$double.sided = 0 and $position='left'">
<xsl:apply-templates select="//copyright[1]" mode="titlepage.mode"/>
</xsl:when>
<xsl:when test="($sequence='first' or $sequence='odd' or $sequence='even') and $position='center'">
<xsl:if test="$pageclass != 'titlepage' and $pageclass != 'lot'">
<xsl:apply-templates select="." mode="titleabbrev.markup"/>
</xsl:if>
</xsl:when>
<xsl:when test="$double.sided = 0 and $position='right'">
<fo:page-number/>
</xsl:when>
<xsl:when test="$sequence='blank'">
<!-- nop -->
</xsl:when>
<xsl:otherwise>
<!-- nop -->
</xsl:otherwise>
</xsl:choose>
</fo:block>
</xsl:template>
</xsl:stylesheet>
<!-- vim: set shiftwidth=2 tabstop=2 expandtab: -->
+182
View File
@@ -0,0 +1,182 @@
<?xml version='1.0'?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
<!-- ********************************************************************
SOGo Documentation Docbook FO Parameters
This file is part of the SOGo project.
Authors:
- Inverse inc. <info@inverse.ca>
Copyright (C) 2011-2014 Inverse inc.
License: GFDL 1.2 or later. http://www.gnu.org/licenses/fdl.html
******************************************************************** -->
<!--
Global Tasks
TODO prettier revhistory
TODO prettier Table of Contents
TODO generate PDF table of contents (like OSX's Preview shows on the right hand side)
TODO title 2
- align with text?
- more above whitespace
TODO change the bullet for a prettier one
TODO title 3 and 4
- align with text?
- should be easier to differentiate (check network guide)
TODO icon on line wrap in monospace boxes
TODO caution, notes, warnings, etc.
- box around it
- sexy icon
TODO -> is converted into an arrow but it's not pretty (is it font or docbook-thingy?)
-->
<!--
Load default values
Real upstream schema is at:
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
but we decided to load all sensible local xsd since it only produce a warning on missing imports.
-->
<!-- CentOS / RHEL -->
<xsl:import href="/usr/share/sgml/docbook/xsl-stylesheets/fo/docbook.xsl"/>
<!-- Debian / Ubuntu -->
<xsl:import href="/usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl"/>
<!-- OSX through mac ports -->
<xsl:import href="/opt/local/share/xsl/docbook-xsl/fo/docbook.xsl"/>
<!-- title page extra styling -->
<xsl:import href="titlepage-fo.xsl"/>
<!-- header / footer extra styling -->
<xsl:import href="headerfooter-fo.xsl"/>
<!-- attaching an image to the verso legalnotice component -->
<xsl:template match="legalnotice" mode="book.titlepage.verso.mode">
<xsl:apply-templates mode="titlepage.mode"/>
<fo:block text-align="right">
<fo:external-graphic src="url('images/inverse-logo.jpg')" width="3in" content-width="scale-to-fit"/>
</fo:block>
</xsl:template>
<!-- stylesheet options -->
<xsl:param name="title.font.family">Lato-Medium</xsl:param>
<xsl:param name="chapter.autolabel" select="0"/>
<xsl:attribute-set name="component.title.properties">
<xsl:attribute name="padding-bottom">2.5em</xsl:attribute>
<xsl:attribute name="border-bottom">solid 2px</xsl:attribute>
<xsl:attribute name="margin-bottom">1em</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="section.title.level1.properties">
<xsl:attribute name="border-bottom">solid 1px</xsl:attribute>
<xsl:attribute name="margin-top">2em</xsl:attribute>
<xsl:attribute name="margin-bottom">1em</xsl:attribute>
</xsl:attribute-set>
<!-- titles spacing -->
<xsl:attribute-set name="section.title.level2.properties">
<xsl:attribute name="margin-top">1em</xsl:attribute>
</xsl:attribute-set>
<!-- default fonts -->
<xsl:param name="body.font.family">Lato-Light</xsl:param>
<xsl:param name="body.font.master">10</xsl:param>
<xsl:param name="monospace.font.family">Incosolata</xsl:param>
<!-- revision table layout -->
<xsl:attribute-set name="revhistory.title.properties">
<xsl:attribute name="font-size">12pt</xsl:attribute>
<xsl:attribute name="font-weight">bold</xsl:attribute>
<xsl:attribute name="text-align">center</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="revhistory.table.properties">
<xsl:attribute name="break-before">page</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="revhistory.table.cell.properties">
<xsl:attribute name="border-bottom">1px solid</xsl:attribute>
</xsl:attribute-set>
<!-- Table Of Contents (TOC) options -->
<!-- We only want 2 level of ToC depth -->
<xsl:param name="toc.section.depth" select="1"/>
<!-- titles left margin -->
<xsl:attribute-set name="section.title.properties">
<xsl:attribute name="start-indent"><xsl:value-of select="$body.start.indent"/></xsl:attribute>
</xsl:attribute-set>
<!-- lists type -->
<xsl:template name="itemizedlist.label.markup">
<xsl:param name="itemsymbol" select="'square'"/>
<xsl:choose>
<xsl:when test="$itemsymbol='square'"><fo:inline font-family="Lato-Light">&#x25aa;</fo:inline></xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template name="next.itemsymbol">
<xsl:param name="itemsymbol" select="'default'"/>
<xsl:choose>
<xsl:otherwise>square</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- admonition -->
<xsl:param name="admon.graphics" select="1"></xsl:param>
<xsl:param name="admon.graphics.path">images/</xsl:param>
<xsl:param name="admon.graphics.extension">.png</xsl:param>
<xsl:attribute-set name="graphical.admonition.properties">
<xsl:attribute name="border-top">1px solid</xsl:attribute>
<xsl:attribute name="border-bottom">1px solid</xsl:attribute>
<xsl:attribute name="padding-top">0.5em</xsl:attribute>
<xsl:attribute name="padding-bottom">0.5em</xsl:attribute>
<xsl:attribute name="margin-left">2em</xsl:attribute>
</xsl:attribute-set>
<!-- grey boxes around code (screen, programlisting) -->
<xsl:param name="shade.verbatim" select="1"/>
<xsl:attribute-set name="shade.verbatim.style">
<xsl:attribute name="background-color">#E0E0E0</xsl:attribute>
<xsl:attribute name="border">thin #9F9F9F solid</xsl:attribute>
<xsl:attribute name="margin">0pt</xsl:attribute>
<xsl:attribute name="padding">0.5em</xsl:attribute>
<!-- prevent page breaks in screen and programlisting tags -->
<xsl:attribute name="keep-together.within-column">always</xsl:attribute>
</xsl:attribute-set>
<!-- breaking long lines in code (screen, programlisting) -->
<xsl:attribute-set name="monospace.verbatim.properties">
<xsl:attribute name="wrap-option">wrap</xsl:attribute>
</xsl:attribute-set>
<!-- don't show raw links in [ .. ] after a link -->
<xsl:param name="ulink.show" select="0"/>
<!-- blue underlined hyperlink -->
<xsl:attribute-set name="xref.properties">
<xsl:attribute name="color">blue</xsl:attribute>
<xsl:attribute name="text-decoration">underline</xsl:attribute>
</xsl:attribute-set>
<!-- strong emphasis in bold -->
<xsl:template match="emphasis[@role='strong']">
<fo:inline font-family="Lato" font-weight="normal">
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
<!-- copyright in range instead of seperated years -->
<xsl:param name="make.year.ranges" select="1" />
<!-- variablelist behavior (asciidoc's term:: lists) -->
<!-- <xsl:param name="variablelist.term.break.after" select="1" /> -->
</xsl:stylesheet>
<!-- vim: set shiftwidth=2 tabstop=2 expandtab: -->
@@ -0,0 +1,96 @@
<!DOCTYPE t:templates [
<!ENTITY hsize0 "10pt">
<!ENTITY hsize1 "12pt">
<!ENTITY hsize2 "14.4pt">
<!ENTITY hsize3 "17.28pt">
<!ENTITY hsize4 "20.736pt">
<!ENTITY hsize5 "24.8832pt">
<!ENTITY hsize0space "7.5pt"> <!-- 0.75 * hsize0 -->
<!ENTITY hsize1space "9pt"> <!-- 0.75 * hsize1 -->
<!ENTITY hsize2space "10.8pt"> <!-- 0.75 * hsize2 -->
<!ENTITY hsize3space "12.96pt"> <!-- 0.75 * hsize3 -->
<!ENTITY hsize4space "15.552pt"> <!-- 0.75 * hsize4 -->
<!ENTITY hsize5space "18.6624pt"> <!-- 0.75 * hsize5 -->
]>
<t:templates xmlns:t="http://nwalsh.com/docbook/xsl/template/1.0"
xmlns:param="http://nwalsh.com/docbook/xsl/template/1.0/param"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- ********************************************************************
SOGo title page
This file is part of the SOGo project.
Authors:
- Inverse inc. <info@inverse.ca>
Copyright (C) 2011-2014 Inverse inc.
License: GFDL 1.2 or later. http://www.gnu.org/licenses/fdl.html
******************************************************************** -->
<!--
If you make changes you need to rebuild XSL:
xsltproc -o docs/docbook/xsl/titlepage-fo.xsl \
/usr/share/xml/docbook/stylesheet/docbook-xsl/template/titlepage.xsl \
docs/docbook/xsl/titlepage-fo.xml
On some platforms the titlepage.xsl is located elsewhere:
* OSX: /opt/local/share/xsl/docbook-xsl/template/titlepage.xsl
This is a customized version of docbook-xsl/fo/titlepage.templates.xml.
I removed every section except the book one. Feel free to add more if more
customization are required.
-->
<t:titlepage t:element="book" t:wrapper="fo:block">
<t:titlepage-content t:side="recto">
<mediaobject/>
<title
t:named-template="division.title"
param:node="ancestor-or-self::book[1]"
text-align="right"
font-size="&hsize5;"
space-before="&hsize5space;"
font-weight="bold"
font-family="{$title.fontset}"
margin-top="8em"/>
<subtitle
text-align="right"
font-size="&hsize4;"
space-before="&hsize4space;"
font-family="{$title.fontset}"
border-bottom="solid"/>
</t:titlepage-content>
<t:titlepage-content t:side="verso">
<title
font-size="&hsize2;"
font-weight="bold"
font-family="{$title.fontset}"/>
<corpauthor/>
<authorgroup t:named-template="verso.authorgroup"/>
<author/>
<othercredit/>
<releaseinfo space-before="0.5em"/>
<pubdate space-before="1em"/>
<copyright/>
<abstract/>
<legalnotice font-size="8pt"/>
</t:titlepage-content>
<t:titlepage-separator>
<fo:block break-after="page"/>
</t:titlepage-separator>
<t:titlepage-before t:side="recto">
</t:titlepage-before>
<t:titlepage-before t:side="verso">
<fo:block break-after="page"/>
</t:titlepage-before>
</t:titlepage>
</t:templates>
+208
View File
@@ -0,0 +1,208 @@
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" version="1.0" exclude-result-prefixes="exsl">
<!-- This stylesheet was created by template/titlepage.xsl-->
<xsl:template name="book.titlepage.recto">
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/mediaobject"/>
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/mediaobject"/>
<xsl:choose>
<xsl:when test="bookinfo/title">
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/title"/>
</xsl:when>
<xsl:when test="info/title">
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/title"/>
</xsl:when>
<xsl:when test="title">
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="title"/>
</xsl:when>
</xsl:choose>
<xsl:choose>
<xsl:when test="bookinfo/subtitle">
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/subtitle"/>
</xsl:when>
<xsl:when test="info/subtitle">
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/subtitle"/>
</xsl:when>
<xsl:when test="subtitle">
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="subtitle"/>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template name="book.titlepage.verso">
<xsl:choose>
<xsl:when test="bookinfo/title">
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/title"/>
</xsl:when>
<xsl:when test="info/title">
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/title"/>
</xsl:when>
<xsl:when test="title">
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="title"/>
</xsl:when>
</xsl:choose>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/corpauthor"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/corpauthor"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/authorgroup"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/authorgroup"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/author"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/author"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/othercredit"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/othercredit"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/releaseinfo"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/releaseinfo"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/pubdate"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/pubdate"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/copyright"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/copyright"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/abstract"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/abstract"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="bookinfo/legalnotice"/>
<xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/legalnotice"/>
</xsl:template>
<xsl:template name="book.titlepage.separator"><fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" break-after="page"/>
</xsl:template>
<xsl:template name="book.titlepage.before.recto">
</xsl:template>
<xsl:template name="book.titlepage.before.verso"><fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" break-after="page"/>
</xsl:template>
<xsl:template name="book.titlepage">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:variable name="recto.content">
<xsl:call-template name="book.titlepage.before.recto"/>
<xsl:call-template name="book.titlepage.recto"/>
</xsl:variable>
<xsl:variable name="recto.elements.count">
<xsl:choose>
<xsl:when test="function-available('exsl:node-set')"><xsl:value-of select="count(exsl:node-set($recto.content)/*)"/></xsl:when>
<xsl:when test="contains(system-property('xsl:vendor'), 'Apache Software Foundation')">
<!--Xalan quirk--><xsl:value-of select="count(exsl:node-set($recto.content)/*)"/></xsl:when>
<xsl:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="(normalize-space($recto.content) != '') or ($recto.elements.count &gt; 0)">
<fo:block><xsl:copy-of select="$recto.content"/></fo:block>
</xsl:if>
<xsl:variable name="verso.content">
<xsl:call-template name="book.titlepage.before.verso"/>
<xsl:call-template name="book.titlepage.verso"/>
</xsl:variable>
<xsl:variable name="verso.elements.count">
<xsl:choose>
<xsl:when test="function-available('exsl:node-set')"><xsl:value-of select="count(exsl:node-set($verso.content)/*)"/></xsl:when>
<xsl:when test="contains(system-property('xsl:vendor'), 'Apache Software Foundation')">
<!--Xalan quirk--><xsl:value-of select="count(exsl:node-set($verso.content)/*)"/></xsl:when>
<xsl:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="(normalize-space($verso.content) != '') or ($verso.elements.count &gt; 0)">
<fo:block><xsl:copy-of select="$verso.content"/></fo:block>
</xsl:if>
<xsl:call-template name="book.titlepage.separator"/>
</fo:block>
</xsl:template>
<xsl:template match="*" mode="book.titlepage.recto.mode">
<!-- if an element isn't found in this mode, -->
<!-- try the generic titlepage.mode -->
<xsl:apply-templates select="." mode="titlepage.mode"/>
</xsl:template>
<xsl:template match="*" mode="book.titlepage.verso.mode">
<!-- if an element isn't found in this mode, -->
<!-- try the generic titlepage.mode -->
<xsl:apply-templates select="." mode="titlepage.mode"/>
</xsl:template>
<xsl:template match="mediaobject" mode="book.titlepage.recto.auto.mode">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.recto.style">
<xsl:apply-templates select="." mode="book.titlepage.recto.mode"/>
</fo:block>
</xsl:template>
<xsl:template match="title" mode="book.titlepage.recto.auto.mode">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.recto.style" text-align="right" font-size="24.8832pt" space-before="18.6624pt" font-weight="bold" font-family="{$title.fontset}" margin-top="8em">
<xsl:call-template name="division.title">
<xsl:with-param name="node" select="ancestor-or-self::book[1]"/>
</xsl:call-template>
</fo:block>
</xsl:template>
<xsl:template match="subtitle" mode="book.titlepage.recto.auto.mode">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.recto.style" text-align="right" font-size="20.736pt" space-before="15.552pt" font-family="{$title.fontset}" border-bottom="solid">
<xsl:apply-templates select="." mode="book.titlepage.recto.mode"/>
</fo:block>
</xsl:template>
<xsl:template match="title" mode="book.titlepage.verso.auto.mode">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style" font-size="14.4pt" font-weight="bold" font-family="{$title.fontset}">
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
</fo:block>
</xsl:template>
<xsl:template match="corpauthor" mode="book.titlepage.verso.auto.mode">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style">
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
</fo:block>
</xsl:template>
<xsl:template match="authorgroup" mode="book.titlepage.verso.auto.mode">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style">
<xsl:call-template name="verso.authorgroup">
</xsl:call-template>
</fo:block>
</xsl:template>
<xsl:template match="author" mode="book.titlepage.verso.auto.mode">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style">
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
</fo:block>
</xsl:template>
<xsl:template match="othercredit" mode="book.titlepage.verso.auto.mode">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style">
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
</fo:block>
</xsl:template>
<xsl:template match="releaseinfo" mode="book.titlepage.verso.auto.mode">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style" space-before="0.5em">
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
</fo:block>
</xsl:template>
<xsl:template match="pubdate" mode="book.titlepage.verso.auto.mode">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style" space-before="1em">
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
</fo:block>
</xsl:template>
<xsl:template match="copyright" mode="book.titlepage.verso.auto.mode">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style">
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
</fo:block>
</xsl:template>
<xsl:template match="abstract" mode="book.titlepage.verso.auto.mode">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style">
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
</fo:block>
</xsl:template>
<xsl:template match="legalnotice" mode="book.titlepage.verso.auto.mode">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="book.titlepage.verso.style" font-size="8pt">
<xsl:apply-templates select="." mode="book.titlepage.verso.mode"/>
</fo:block>
</xsl:template>
</xsl:stylesheet>
+24
View File
@@ -0,0 +1,24 @@
<!-- TODO have the build system take care of this -->
<releaseinfo>Version 2.2.10 - November 2014</releaseinfo>
<subtitle>for version 2.2.10</subtitle>
<date>2014-11-21</date>
<legalnotice>
<para>Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".</para>
<!-- font licenses -->
<para>The fonts used in this guide are licensed under the SIL Open Font License, Version 1.1. This license is available with a FAQ at: <ulink url="http://scripts.sil.org/OFL">http://scripts.sil.org/OFL</ulink></para>
<para>Copyright © Łukasz Dziedzic, <ulink url="http://www.latofonts.com/">http://www.latofonts.com</ulink>, with Reserved Font Name: "Lato".</para>
<para>Copyright © Raph Levien, <ulink url="http://levien.com/">http://levien.com/</ulink>, with Reserved Font Name: "Inconsolata".</para>
</legalnotice>
<mediaobject>
<objectinfo>
<corpname>Inverse inc.</corpname>
</objectinfo>
<textobject>
<phrase>SOGo logo</phrase>
</textobject>
<imageobject>
<imagedata align="left" width="4in" format="PNG" fileref="images/sogo-logo.png" />
</imageobject>
</mediaobject>
+32
View File
@@ -0,0 +1,32 @@
<fop version="1.0">
<renderers>
<renderer mime="application/pdf">
<fonts>
<font metrics-url="fonts/inconsolata.xml" kerning="yes" embed-url="fonts/inconsolata.ttf">
<font-triplet name="Incosolata" style="normal" weight="normal"/>
</font>
<font metrics-url="fonts/lato/Lato-Regular.xml" kerning="yes" embed-url="fonts/lato/Lato-Regular.ttf">
<font-triplet name="Lato" style="normal" weight="normal"/>
</font>
<font metrics-url="fonts/lato/Lato-Italic.xml" kerning="yes" embed-url="fonts/lato/Lato-Italic.ttf">
<font-triplet name="Lato" style="italic" weight="normal"/>
</font>
<font metrics-url="fonts/lato/Lato-Light.xml" kerning="yes" embed-url="fonts/lato/Lato-Light.ttf">
<font-triplet name="Lato-Light" style="normal" weight="normal"/>
</font>
<font metrics-url="fonts/lato/Lato-LightItalic.xml" kerning="yes" embed-url="fonts/lato/Lato-LightItalic.ttf">
<font-triplet name="Lato-Light" style="italic" weight="normal"/>
</font>
<font metrics-url="fonts/lato/Lato-Medium.xml" kerning="yes" embed-url="fonts/lato/Lato-Medium.ttf">
<font-triplet name="Lato-Medium" style="normal" weight="normal"/>
</font>
<font metrics-url="fonts/lato/Lato-MediumItalic.xml" kerning="yes" embed-url="fonts/lato/Lato-MediumItalic.ttf">
<font-triplet name="Lato-Medium" style="italic" weight="normal"/>
</font>
<font metrics-url="fonts/lato/Lato-Semibold.xml" kerning="yes" embed-url="fonts/lato/Lato-Semibold.ttf">
<font-triplet name="Lato-Semibold" style="normal" weight="normal"/>
</font>
</fonts>
</renderer>
</renderers>
</fop>
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Inconsolata</font-name><full-name>Inconsolata</full-name><family-name>Inconsolata</family-name><embed/><cap-height>624</cap-height><x-height>458</x-height><ascender>820</ascender><descender>-180</descender><bbox><left>-1</left><bottom>-177</bottom><right>510</right><top>835</top></bbox><flags>33</flags><stemv>0</stemv><italicangle>0</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="3" ue="126" us="32"/><bf gi="98" ue="255" us="160"/><bf gi="194" ue="263" us="258"/><bf gi="200" ue="273" us="268"/><bf gi="206" ue="283" us="280"/><bf gi="210" ue="287" us="286"/><bf gi="212" ue="305" us="304"/><bf gi="214" ue="314" us="312"/><bf gi="217" ue="318" us="317"/><bf gi="219" ue="324" us="321"/><bf gi="223" ue="328" us="327"/><bf gi="225" ue="331" us="330"/><bf gi="227" ue="333" us="333"/><bf gi="228" ue="341" us="336"/><bf gi="234" ue="347" us="344"/><bf gi="238" ue="357" us="350"/><bf gi="246" ue="369" us="366"/><bf gi="250" ue="382" us="376"/><bf gi="257" ue="402" us="402"/><bf gi="258" ue="567" us="567"/><bf gi="259" ue="711" us="710"/><bf gi="261" ue="713" us="713"/><bf gi="262" ue="715" us="715"/><bf gi="263" ue="733" us="728"/><bf gi="269" ue="8218" us="8216"/><bf gi="272" ue="8222" us="8220"/><bf gi="275" ue="8226" us="8224"/><bf gi="278" ue="8230" us="8230"/><bf gi="279" ue="8250" us="8249"/><bf gi="281" ue="8260" us="8260"/><bf gi="282" ue="8308" us="8308"/><bf gi="283" ue="8364" us="8364"/><bf gi="284" ue="8482" us="8482"/><bf gi="285" ue="8593" us="8593"/><bf gi="286" ue="8595" us="8595"/><bf gi="287" ue="8722" us="8722"/><bf gi="288" ue="9251" us="9251"/><bf gi="0" ue="65535" us="65535"/></bfranges><cid-widths start-index="0"><wx w="500"/><wx w="0"/><wx w="333"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wx w="500"/><wLine truncated
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Lato-Black</font-name><full-name>Lato Black</full-name><family-name>Lato</family-name><embed/><cap-height>728</cap-height><x-height>518</x-height><ascender>805</ascender><descender>-195</descender><bbox><left>-654</left><bottom>-299</bottom><right>1356</right><top>1116</top></bbox><flags>33</flags><stemv>0</stemv><italicangle>0</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="1" ue="0" us="0"/><bf gi="171" ue="13" us="13"/><bf gi="2" ue="32" us="32"/><bf gi="82" ue="33" us="33"/><bf gi="122" ue="34" us="34"/><bf gi="134" ue="35" us="35"/><bf gi="130" ue="36" us="36"/><bf gi="166" ue="37" us="37"/><bf gi="123" ue="38" us="38"/><bf gi="121" ue="39" us="39"/><bf gi="108" ue="41" us="40"/><bf gi="114" ue="42" us="42"/><bf gi="144" ue="43" us="43"/><bf gi="84" ue="44" us="44"/><bf gi="102" ue="45" us="45"/><bf gi="87" ue="46" us="46"/><bf gi="99" ue="47" us="47"/><bf gi="135" ue="53" us="48"/><bf gi="164" ue="54" us="54"/><bf gi="141" ue="55" us="55"/><bf gi="165" ue="56" us="56"/><bf gi="142" ue="57" us="57"/><bf gi="86" ue="58" us="58"/><bf gi="85" ue="59" us="59"/><bf gi="149" ue="60" us="60"/><bf gi="146" ue="61" us="61"/><bf gi="150" ue="62" us="62"/><bf gi="83" ue="63" us="63"/><bf gi="124" ue="64" us="64"/><bf gi="3" ue="65" us="65"/><bf gi="5" ue="67" us="66"/><bf gi="8" ue="79" us="68"/><bf gi="22" ue="90" us="80"/><bf gi="110" ue="91" us="91"/><bf gi="101" ue="92" us="92"/><bf gi="111" ue="93" us="93"/><bf gi="119" ue="94" us="94"/><bf gi="105" ue="95" us="95"/><bf gi="68" ue="96" us="96"/><bf gi="33" ue="97" us="97"/><bf gi="35" ue="99" us="98"/><bf gi="38" ue="102" us="100"/><bf gi="43" ue="105" us="103"/><bf gi="47" ue="107" us="106"/><bf gi="163" ue="108" us="108"/><bf gi="49" ue="111" us="109"/><bf gi="54" ue="115" us="112"/><bf gi="59" ue="122" us="116"/><bf gi="112" ue="123" us="123"/><bf gi="100" ue="124" us="124"/><bf gi="113" ue="125" us="125"/><bf gi="120" ue="126" us="126"/><bf gi="2" ue="160" us="160"/><bf gi="167" ue="161" us="161"/><bf gi="131" ue="163" us="162"/><bf gi="455" ue="164" us="164"/><bf gi="133" ue="165" us="165"/><bf gi="452" ue="166" us="166"/><bf gi="117" ue="167" us="167"/><bf gi="73" ue="168" us="168"/><bf gi="125" ue="169" us="169"/><bf gi="66" ue="170" us="170"/><bf gi="97" ue="171" us="171"/><bf gi="154" ue="172" us="172"/><bf gi="102" ue="173" us="173"/><bf gi="126" ue="174" us="174"/><bf gi="74" ue="175" us="175"/><bf gi="128" ue="176" us="176"/><bf gi="151" ue="177" us="177"/><bf gi="1202" ue="179" us="178"/><bf gi="69" ue="180" us="180"/><bf gi="224" ue="181" us="181"/><bf gi="118" ue="182" us="182"/><bf gi="107" ue="183" us="183"/><bf gi="79" ue="184" us="184"/><bf gi="1204" ue="185" us="185"/><bf gi="67" ue="186" us="186"/><bf gi="98" ue="187" us="187"/><bf gi="1205" ue="190" us="188"/><bf gi="168" ue="191" us="191"/><bf gi="172" ue="197" us="192"/><bf gi="4" ue="198" us="198"/><bf gi="7" ue="199" us="199"/><bf gi="178" ue="207" us="200"/><bf gi="226" ue="208" us="208"/><bf gi="186" ue="214" us="209"/><bf gi="517" ue="215" us="215"/><bf gi="20" ue="216" us="216"/><bf gi="192" ue="220" us="217"/><bf gi="2203" ue="221" us="221"/><bf gi="233" ue="222" us="222"/><bf gi="58" ue="223" us="223"/><bf gi="197" ue="229" us="224"/><bf gi="34" ue="230" us="230"/><bf gi="37" ue="231" us="231"/><bf gi="203" ue="239" us="232"/><bf gi="244" ue="240" us="240"/><bf gi="211" ue="246" us="241"/><bf gi="145" ue="247" us="247"/><bf gi="52" ue="248" us="248"/><bf gi="217" ue="252" us="249"/><bf gi="2538" ue="253" us="253"/><bf gi="285" ue="254" us="254"/><bf gi="221" ue="255" us="255"/><bf gi="1889" ue="256" us="256"/><bf gi="2229" ue="257" us="257"/><bf gi="1890" ue="258" us="258"/><bf gi="2230" ue="259" us="259"/><bf gi="225" ue="260" us="260"/><bf gi="237" ue="261" us="261"/><bf gi="1947" ue="262" us="262"/><bf gi="2263" ue="263" us="263"/><bf gi="1948" ue="264" us="264"/><bf gi="2264" ue="265" us="265"/><bf gi="1950" ue="266" us="266"/><bf gi="2266" ue="267" us="267"/><bf gi="1949" ue="268" us="268"/><bf gi="2265" ue="269" us="269"/><bf gi="1955" ue="270" us="270"/><bf gi="242" ue="271" us="271"/><bf gi="1962" ue="272" us="272"/><bf gi="243" ue="273" us="273"/><bf gi="1965" ue="274" us="274"/><bf gi="2279" ue="275" us="275"/><bf gi="1966" ue="276" us="276"/><bf gi="2280" ue="277" us="277"/><bf gi="1967" ue="278" us="278"/><bf gi="2281" ue="279" us="279"/><bf gi="227" ue="280" us="280"/><bf gi="245" ue="281" us="281"/><bf gi="1964" ue="282" us="282"/><bf gi="2278" ue="283" us="283"/><bf gi="2000" ue="284" us="284"/><bf gi="2322" ue="285" us="285"/><bf gi="2001" ue="286" us="286"/><bf gi="2323" ue="287" us="287"/><bf gi="2002" ue="288" us="288"/><bf gi="2324" ue="289" us="289"/><bf gi="2003" ue="290" us="290"/><bf gi="2325" ue="291" us="291"/><bf gi="2007" ue="292" us="292"/><bf gi="276" ue="293" us=Line truncated
Binary file not shown.
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Lato-BlackItalic</font-name><full-name>Lato Black Italic</full-name><family-name>Lato</family-name><embed/><cap-height>728</cap-height><x-height>518</x-height><ascender>805</ascender><descender>-195</descender><bbox><left>-537</left><bottom>-297</bottom><right>1295</right><top>1114</top></bbox><flags>97</flags><stemv>0</stemv><italicangle>-7</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="1" ue="0" us="0"/><bf gi="169" ue="13" us="13"/><bf gi="2" ue="32" us="32"/><bf gi="81" ue="33" us="33"/><bf gi="120" ue="34" us="34"/><bf gi="132" ue="35" us="35"/><bf gi="128" ue="36" us="36"/><bf gi="164" ue="37" us="37"/><bf gi="121" ue="38" us="38"/><bf gi="119" ue="39" us="39"/><bf gi="106" ue="41" us="40"/><bf gi="112" ue="42" us="42"/><bf gi="142" ue="43" us="43"/><bf gi="83" ue="44" us="44"/><bf gi="100" ue="45" us="45"/><bf gi="85" ue="46" us="46"/><bf gi="97" ue="47" us="47"/><bf gi="133" ue="53" us="48"/><bf gi="162" ue="54" us="54"/><bf gi="139" ue="55" us="55"/><bf gi="163" ue="56" us="56"/><bf gi="140" ue="57" us="57"/><bf gi="170" ue="58" us="58"/><bf gi="84" ue="59" us="59"/><bf gi="147" ue="60" us="60"/><bf gi="144" ue="61" us="61"/><bf gi="148" ue="62" us="62"/><bf gi="82" ue="63" us="63"/><bf gi="122" ue="64" us="64"/><bf gi="3" ue="65" us="65"/><bf gi="5" ue="67" us="66"/><bf gi="8" ue="79" us="68"/><bf gi="22" ue="90" us="80"/><bf gi="108" ue="91" us="91"/><bf gi="99" ue="92" us="92"/><bf gi="109" ue="93" us="93"/><bf gi="117" ue="94" us="94"/><bf gi="103" ue="95" us="95"/><bf gi="68" ue="96" us="96"/><bf gi="33" ue="97" us="97"/><bf gi="35" ue="99" us="98"/><bf gi="38" ue="102" us="100"/><bf gi="43" ue="105" us="103"/><bf gi="47" ue="107" us="106"/><bf gi="161" ue="108" us="108"/><bf gi="49" ue="111" us="109"/><bf gi="54" ue="115" us="112"/><bf gi="59" ue="122" us="116"/><bf gi="110" ue="123" us="123"/><bf gi="98" ue="124" us="124"/><bf gi="111" ue="125" us="125"/><bf gi="118" ue="126" us="126"/><bf gi="2" ue="160" us="160"/><bf gi="165" ue="161" us="161"/><bf gi="129" ue="163" us="162"/><bf gi="455" ue="164" us="164"/><bf gi="131" ue="165" us="165"/><bf gi="452" ue="166" us="166"/><bf gi="115" ue="167" us="167"/><bf gi="171" ue="168" us="168"/><bf gi="123" ue="169" us="169"/><bf gi="66" ue="170" us="170"/><bf gi="95" ue="171" us="171"/><bf gi="152" ue="172" us="172"/><bf gi="100" ue="173" us="173"/><bf gi="124" ue="174" us="174"/><bf gi="73" ue="175" us="175"/><bf gi="126" ue="176" us="176"/><bf gi="149" ue="177" us="177"/><bf gi="1202" ue="179" us="178"/><bf gi="69" ue="180" us="180"/><bf gi="224" ue="181" us="181"/><bf gi="116" ue="182" us="182"/><bf gi="105" ue="183" us="183"/><bf gi="78" ue="184" us="184"/><bf gi="1204" ue="185" us="185"/><bf gi="67" ue="186" us="186"/><bf gi="96" ue="187" us="187"/><bf gi="1205" ue="190" us="188"/><bf gi="166" ue="191" us="191"/><bf gi="172" ue="197" us="192"/><bf gi="4" ue="198" us="198"/><bf gi="7" ue="199" us="199"/><bf gi="178" ue="207" us="200"/><bf gi="226" ue="208" us="208"/><bf gi="186" ue="214" us="209"/><bf gi="517" ue="215" us="215"/><bf gi="20" ue="216" us="216"/><bf gi="192" ue="220" us="217"/><bf gi="1973" ue="221" us="221"/><bf gi="233" ue="222" us="222"/><bf gi="58" ue="223" us="223"/><bf gi="197" ue="229" us="224"/><bf gi="34" ue="230" us="230"/><bf gi="37" ue="231" us="231"/><bf gi="203" ue="239" us="232"/><bf gi="244" ue="240" us="240"/><bf gi="211" ue="246" us="241"/><bf gi="143" ue="247" us="247"/><bf gi="52" ue="248" us="248"/><bf gi="217" ue="252" us="249"/><bf gi="2312" ue="253" us="253"/><bf gi="285" ue="254" us="254"/><bf gi="221" ue="255" us="255"/><bf gi="1659" ue="256" us="256"/><bf gi="1999" ue="257" us="257"/><bf gi="1660" ue="258" us="258"/><bf gi="2000" ue="259" us="259"/><bf gi="225" ue="260" us="260"/><bf gi="237" ue="261" us="261"/><bf gi="1717" ue="262" us="262"/><bf gi="2033" ue="263" us="263"/><bf gi="1718" ue="264" us="264"/><bf gi="2034" ue="265" us="265"/><bf gi="1720" ue="266" us="266"/><bf gi="2036" ue="267" us="267"/><bf gi="1719" ue="268" us="268"/><bf gi="2035" ue="269" us="269"/><bf gi="1725" ue="270" us="270"/><bf gi="242" ue="271" us="271"/><bf gi="1732" ue="272" us="272"/><bf gi="243" ue="273" us="273"/><bf gi="1735" ue="274" us="274"/><bf gi="2049" ue="275" us="275"/><bf gi="1736" ue="276" us="276"/><bf gi="2050" ue="277" us="277"/><bf gi="1737" ue="278" us="278"/><bf gi="2051" ue="279" us="279"/><bf gi="227" ue="280" us="280"/><bf gi="245" ue="281" us="281"/><bf gi="1734" ue="282" us="282"/><bf gi="2048" ue="283" us="283"/><bf gi="1770" ue="284" us="284"/><bf gi="2092" ue="285" us="285"/><bf gi="1771" ue="286" us="286"/><bf gi="2093" ue="287" us="287"/><bf gi="1772" ue="288" us="288"/><bf gi="2094" ue="289" us="289"/><bf gi="1773" ue="290" us="290"/><bf gi="2095" ue="291" us="291"/><bf gi="1777" ue="292" us="292"/><bf gi="276Line truncated
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Lato-Bold</font-name><full-name>Lato Bold</full-name><family-name>Lato</family-name><embed/><cap-height>723</cap-height><x-height>513</x-height><ascender>805</ascender><descender>-195</descender><bbox><left>-603</left><bottom>-285</bottom><right>1344</right><top>1099</top></bbox><flags>33</flags><stemv>0</stemv><italicangle>0</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="1" ue="0" us="0"/><bf gi="171" ue="13" us="13"/><bf gi="2" ue="32" us="32"/><bf gi="82" ue="33" us="33"/><bf gi="122" ue="34" us="34"/><bf gi="134" ue="35" us="35"/><bf gi="130" ue="36" us="36"/><bf gi="166" ue="37" us="37"/><bf gi="123" ue="38" us="38"/><bf gi="121" ue="39" us="39"/><bf gi="108" ue="41" us="40"/><bf gi="114" ue="42" us="42"/><bf gi="144" ue="43" us="43"/><bf gi="84" ue="44" us="44"/><bf gi="102" ue="45" us="45"/><bf gi="87" ue="46" us="46"/><bf gi="99" ue="47" us="47"/><bf gi="135" ue="53" us="48"/><bf gi="164" ue="54" us="54"/><bf gi="141" ue="55" us="55"/><bf gi="165" ue="56" us="56"/><bf gi="142" ue="57" us="57"/><bf gi="86" ue="58" us="58"/><bf gi="85" ue="59" us="59"/><bf gi="149" ue="60" us="60"/><bf gi="146" ue="61" us="61"/><bf gi="150" ue="62" us="62"/><bf gi="83" ue="63" us="63"/><bf gi="124" ue="64" us="64"/><bf gi="3" ue="65" us="65"/><bf gi="5" ue="67" us="66"/><bf gi="8" ue="79" us="68"/><bf gi="22" ue="90" us="80"/><bf gi="110" ue="91" us="91"/><bf gi="101" ue="92" us="92"/><bf gi="111" ue="93" us="93"/><bf gi="119" ue="94" us="94"/><bf gi="105" ue="95" us="95"/><bf gi="68" ue="96" us="96"/><bf gi="33" ue="97" us="97"/><bf gi="35" ue="99" us="98"/><bf gi="38" ue="102" us="100"/><bf gi="43" ue="105" us="103"/><bf gi="47" ue="107" us="106"/><bf gi="163" ue="108" us="108"/><bf gi="49" ue="111" us="109"/><bf gi="54" ue="115" us="112"/><bf gi="59" ue="122" us="116"/><bf gi="112" ue="123" us="123"/><bf gi="100" ue="124" us="124"/><bf gi="113" ue="125" us="125"/><bf gi="120" ue="126" us="126"/><bf gi="2" ue="160" us="160"/><bf gi="167" ue="161" us="161"/><bf gi="131" ue="163" us="162"/><bf gi="455" ue="164" us="164"/><bf gi="133" ue="165" us="165"/><bf gi="452" ue="166" us="166"/><bf gi="117" ue="167" us="167"/><bf gi="73" ue="168" us="168"/><bf gi="125" ue="169" us="169"/><bf gi="66" ue="170" us="170"/><bf gi="97" ue="171" us="171"/><bf gi="154" ue="172" us="172"/><bf gi="102" ue="173" us="173"/><bf gi="126" ue="174" us="174"/><bf gi="74" ue="175" us="175"/><bf gi="128" ue="176" us="176"/><bf gi="151" ue="177" us="177"/><bf gi="1202" ue="179" us="178"/><bf gi="69" ue="180" us="180"/><bf gi="224" ue="181" us="181"/><bf gi="118" ue="182" us="182"/><bf gi="107" ue="183" us="183"/><bf gi="79" ue="184" us="184"/><bf gi="1204" ue="185" us="185"/><bf gi="67" ue="186" us="186"/><bf gi="98" ue="187" us="187"/><bf gi="1205" ue="190" us="188"/><bf gi="168" ue="191" us="191"/><bf gi="172" ue="197" us="192"/><bf gi="4" ue="198" us="198"/><bf gi="7" ue="199" us="199"/><bf gi="178" ue="207" us="200"/><bf gi="226" ue="208" us="208"/><bf gi="186" ue="214" us="209"/><bf gi="517" ue="215" us="215"/><bf gi="20" ue="216" us="216"/><bf gi="192" ue="220" us="217"/><bf gi="2203" ue="221" us="221"/><bf gi="233" ue="222" us="222"/><bf gi="58" ue="223" us="223"/><bf gi="197" ue="229" us="224"/><bf gi="34" ue="230" us="230"/><bf gi="37" ue="231" us="231"/><bf gi="203" ue="239" us="232"/><bf gi="244" ue="240" us="240"/><bf gi="211" ue="246" us="241"/><bf gi="145" ue="247" us="247"/><bf gi="52" ue="248" us="248"/><bf gi="217" ue="252" us="249"/><bf gi="2538" ue="253" us="253"/><bf gi="285" ue="254" us="254"/><bf gi="221" ue="255" us="255"/><bf gi="1889" ue="256" us="256"/><bf gi="2229" ue="257" us="257"/><bf gi="1890" ue="258" us="258"/><bf gi="2230" ue="259" us="259"/><bf gi="225" ue="260" us="260"/><bf gi="237" ue="261" us="261"/><bf gi="1947" ue="262" us="262"/><bf gi="2263" ue="263" us="263"/><bf gi="1948" ue="264" us="264"/><bf gi="2264" ue="265" us="265"/><bf gi="1950" ue="266" us="266"/><bf gi="2266" ue="267" us="267"/><bf gi="1949" ue="268" us="268"/><bf gi="2265" ue="269" us="269"/><bf gi="1955" ue="270" us="270"/><bf gi="242" ue="271" us="271"/><bf gi="1962" ue="272" us="272"/><bf gi="243" ue="273" us="273"/><bf gi="1965" ue="274" us="274"/><bf gi="2279" ue="275" us="275"/><bf gi="1966" ue="276" us="276"/><bf gi="2280" ue="277" us="277"/><bf gi="1967" ue="278" us="278"/><bf gi="2281" ue="279" us="279"/><bf gi="227" ue="280" us="280"/><bf gi="245" ue="281" us="281"/><bf gi="1964" ue="282" us="282"/><bf gi="2278" ue="283" us="283"/><bf gi="2000" ue="284" us="284"/><bf gi="2322" ue="285" us="285"/><bf gi="2001" ue="286" us="286"/><bf gi="2323" ue="287" us="287"/><bf gi="2002" ue="288" us="288"/><bf gi="2324" ue="289" us="289"/><bf gi="2003" ue="290" us="290"/><bf gi="2325" ue="291" us="291"/><bf gi="2007" ue="292" us="292"/><bf gi="276" ue="293" us="2Line truncated
Binary file not shown.
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Lato-BoldItalic</font-name><full-name>Lato Bold Italic</full-name><family-name>Lato</family-name><embed/><cap-height>723</cap-height><x-height>513</x-height><ascender>805</ascender><descender>-195</descender><bbox><left>-520</left><bottom>-283</bottom><right>1293</right><top>1097</top></bbox><flags>97</flags><stemv>0</stemv><italicangle>-7</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="1" ue="0" us="0"/><bf gi="169" ue="13" us="13"/><bf gi="2" ue="32" us="32"/><bf gi="81" ue="33" us="33"/><bf gi="120" ue="34" us="34"/><bf gi="132" ue="35" us="35"/><bf gi="128" ue="36" us="36"/><bf gi="164" ue="37" us="37"/><bf gi="121" ue="38" us="38"/><bf gi="119" ue="39" us="39"/><bf gi="106" ue="41" us="40"/><bf gi="112" ue="42" us="42"/><bf gi="142" ue="43" us="43"/><bf gi="83" ue="44" us="44"/><bf gi="100" ue="45" us="45"/><bf gi="85" ue="46" us="46"/><bf gi="97" ue="47" us="47"/><bf gi="133" ue="53" us="48"/><bf gi="162" ue="54" us="54"/><bf gi="139" ue="55" us="55"/><bf gi="163" ue="56" us="56"/><bf gi="140" ue="57" us="57"/><bf gi="170" ue="58" us="58"/><bf gi="84" ue="59" us="59"/><bf gi="147" ue="60" us="60"/><bf gi="144" ue="61" us="61"/><bf gi="148" ue="62" us="62"/><bf gi="82" ue="63" us="63"/><bf gi="122" ue="64" us="64"/><bf gi="3" ue="65" us="65"/><bf gi="5" ue="67" us="66"/><bf gi="8" ue="79" us="68"/><bf gi="22" ue="90" us="80"/><bf gi="108" ue="91" us="91"/><bf gi="99" ue="92" us="92"/><bf gi="109" ue="93" us="93"/><bf gi="117" ue="94" us="94"/><bf gi="103" ue="95" us="95"/><bf gi="68" ue="96" us="96"/><bf gi="33" ue="97" us="97"/><bf gi="35" ue="99" us="98"/><bf gi="38" ue="102" us="100"/><bf gi="43" ue="105" us="103"/><bf gi="47" ue="107" us="106"/><bf gi="161" ue="108" us="108"/><bf gi="49" ue="111" us="109"/><bf gi="54" ue="115" us="112"/><bf gi="59" ue="122" us="116"/><bf gi="110" ue="123" us="123"/><bf gi="98" ue="124" us="124"/><bf gi="111" ue="125" us="125"/><bf gi="118" ue="126" us="126"/><bf gi="2" ue="160" us="160"/><bf gi="165" ue="161" us="161"/><bf gi="129" ue="163" us="162"/><bf gi="455" ue="164" us="164"/><bf gi="131" ue="165" us="165"/><bf gi="452" ue="166" us="166"/><bf gi="115" ue="167" us="167"/><bf gi="171" ue="168" us="168"/><bf gi="123" ue="169" us="169"/><bf gi="66" ue="170" us="170"/><bf gi="95" ue="171" us="171"/><bf gi="152" ue="172" us="172"/><bf gi="100" ue="173" us="173"/><bf gi="124" ue="174" us="174"/><bf gi="73" ue="175" us="175"/><bf gi="126" ue="176" us="176"/><bf gi="149" ue="177" us="177"/><bf gi="1202" ue="179" us="178"/><bf gi="69" ue="180" us="180"/><bf gi="224" ue="181" us="181"/><bf gi="116" ue="182" us="182"/><bf gi="105" ue="183" us="183"/><bf gi="78" ue="184" us="184"/><bf gi="1204" ue="185" us="185"/><bf gi="67" ue="186" us="186"/><bf gi="96" ue="187" us="187"/><bf gi="1205" ue="190" us="188"/><bf gi="166" ue="191" us="191"/><bf gi="172" ue="197" us="192"/><bf gi="4" ue="198" us="198"/><bf gi="7" ue="199" us="199"/><bf gi="178" ue="207" us="200"/><bf gi="226" ue="208" us="208"/><bf gi="186" ue="214" us="209"/><bf gi="517" ue="215" us="215"/><bf gi="20" ue="216" us="216"/><bf gi="192" ue="220" us="217"/><bf gi="1973" ue="221" us="221"/><bf gi="233" ue="222" us="222"/><bf gi="58" ue="223" us="223"/><bf gi="197" ue="229" us="224"/><bf gi="34" ue="230" us="230"/><bf gi="37" ue="231" us="231"/><bf gi="203" ue="239" us="232"/><bf gi="244" ue="240" us="240"/><bf gi="211" ue="246" us="241"/><bf gi="143" ue="247" us="247"/><bf gi="52" ue="248" us="248"/><bf gi="217" ue="252" us="249"/><bf gi="2312" ue="253" us="253"/><bf gi="285" ue="254" us="254"/><bf gi="221" ue="255" us="255"/><bf gi="1659" ue="256" us="256"/><bf gi="1999" ue="257" us="257"/><bf gi="1660" ue="258" us="258"/><bf gi="2000" ue="259" us="259"/><bf gi="225" ue="260" us="260"/><bf gi="237" ue="261" us="261"/><bf gi="1717" ue="262" us="262"/><bf gi="2033" ue="263" us="263"/><bf gi="1718" ue="264" us="264"/><bf gi="2034" ue="265" us="265"/><bf gi="1720" ue="266" us="266"/><bf gi="2036" ue="267" us="267"/><bf gi="1719" ue="268" us="268"/><bf gi="2035" ue="269" us="269"/><bf gi="1725" ue="270" us="270"/><bf gi="242" ue="271" us="271"/><bf gi="1732" ue="272" us="272"/><bf gi="243" ue="273" us="273"/><bf gi="1735" ue="274" us="274"/><bf gi="2049" ue="275" us="275"/><bf gi="1736" ue="276" us="276"/><bf gi="2050" ue="277" us="277"/><bf gi="1737" ue="278" us="278"/><bf gi="2051" ue="279" us="279"/><bf gi="227" ue="280" us="280"/><bf gi="245" ue="281" us="281"/><bf gi="1734" ue="282" us="282"/><bf gi="2048" ue="283" us="283"/><bf gi="1770" ue="284" us="284"/><bf gi="2092" ue="285" us="285"/><bf gi="1771" ue="286" us="286"/><bf gi="2093" ue="287" us="287"/><bf gi="1772" ue="288" us="288"/><bf gi="2094" ue="289" us="289"/><bf gi="1773" ue="290" us="290"/><bf gi="2095" ue="291" us="291"/><bf gi="1777" ue="292" us="292"/><bf gi="276" Line truncated
Binary file not shown.
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Lato-Hairline</font-name><full-name>Lato Hairline</full-name><family-name>Lato</family-name><embed/><cap-height>700</cap-height><x-height>490</x-height><ascender>805</ascender><descender>-195</descender><bbox><left>-459</left><bottom>-259</bottom><right>1340</right><top>1034</top></bbox><flags>33</flags><stemv>0</stemv><italicangle>0</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="1" ue="0" us="0"/><bf gi="171" ue="13" us="13"/><bf gi="2" ue="32" us="32"/><bf gi="82" ue="33" us="33"/><bf gi="122" ue="34" us="34"/><bf gi="134" ue="35" us="35"/><bf gi="130" ue="36" us="36"/><bf gi="166" ue="37" us="37"/><bf gi="123" ue="38" us="38"/><bf gi="121" ue="39" us="39"/><bf gi="108" ue="41" us="40"/><bf gi="114" ue="42" us="42"/><bf gi="144" ue="43" us="43"/><bf gi="84" ue="44" us="44"/><bf gi="102" ue="45" us="45"/><bf gi="87" ue="46" us="46"/><bf gi="99" ue="47" us="47"/><bf gi="135" ue="53" us="48"/><bf gi="164" ue="54" us="54"/><bf gi="141" ue="55" us="55"/><bf gi="165" ue="56" us="56"/><bf gi="142" ue="57" us="57"/><bf gi="86" ue="58" us="58"/><bf gi="85" ue="59" us="59"/><bf gi="149" ue="60" us="60"/><bf gi="146" ue="61" us="61"/><bf gi="150" ue="62" us="62"/><bf gi="83" ue="63" us="63"/><bf gi="124" ue="64" us="64"/><bf gi="3" ue="65" us="65"/><bf gi="5" ue="67" us="66"/><bf gi="8" ue="79" us="68"/><bf gi="22" ue="90" us="80"/><bf gi="110" ue="91" us="91"/><bf gi="101" ue="92" us="92"/><bf gi="111" ue="93" us="93"/><bf gi="119" ue="94" us="94"/><bf gi="105" ue="95" us="95"/><bf gi="68" ue="96" us="96"/><bf gi="33" ue="97" us="97"/><bf gi="35" ue="99" us="98"/><bf gi="38" ue="102" us="100"/><bf gi="43" ue="105" us="103"/><bf gi="47" ue="107" us="106"/><bf gi="163" ue="108" us="108"/><bf gi="49" ue="111" us="109"/><bf gi="54" ue="115" us="112"/><bf gi="59" ue="122" us="116"/><bf gi="112" ue="123" us="123"/><bf gi="100" ue="124" us="124"/><bf gi="113" ue="125" us="125"/><bf gi="120" ue="126" us="126"/><bf gi="2" ue="160" us="160"/><bf gi="167" ue="161" us="161"/><bf gi="131" ue="163" us="162"/><bf gi="455" ue="164" us="164"/><bf gi="133" ue="165" us="165"/><bf gi="452" ue="166" us="166"/><bf gi="117" ue="167" us="167"/><bf gi="73" ue="168" us="168"/><bf gi="125" ue="169" us="169"/><bf gi="66" ue="170" us="170"/><bf gi="97" ue="171" us="171"/><bf gi="154" ue="172" us="172"/><bf gi="102" ue="173" us="173"/><bf gi="126" ue="174" us="174"/><bf gi="74" ue="175" us="175"/><bf gi="128" ue="176" us="176"/><bf gi="151" ue="177" us="177"/><bf gi="1202" ue="179" us="178"/><bf gi="69" ue="180" us="180"/><bf gi="224" ue="181" us="181"/><bf gi="118" ue="182" us="182"/><bf gi="107" ue="183" us="183"/><bf gi="79" ue="184" us="184"/><bf gi="1204" ue="185" us="185"/><bf gi="67" ue="186" us="186"/><bf gi="98" ue="187" us="187"/><bf gi="1205" ue="190" us="188"/><bf gi="168" ue="191" us="191"/><bf gi="172" ue="197" us="192"/><bf gi="4" ue="198" us="198"/><bf gi="7" ue="199" us="199"/><bf gi="178" ue="207" us="200"/><bf gi="226" ue="208" us="208"/><bf gi="186" ue="214" us="209"/><bf gi="517" ue="215" us="215"/><bf gi="20" ue="216" us="216"/><bf gi="192" ue="220" us="217"/><bf gi="2203" ue="221" us="221"/><bf gi="233" ue="222" us="222"/><bf gi="58" ue="223" us="223"/><bf gi="197" ue="229" us="224"/><bf gi="34" ue="230" us="230"/><bf gi="37" ue="231" us="231"/><bf gi="203" ue="239" us="232"/><bf gi="244" ue="240" us="240"/><bf gi="211" ue="246" us="241"/><bf gi="145" ue="247" us="247"/><bf gi="52" ue="248" us="248"/><bf gi="217" ue="252" us="249"/><bf gi="2538" ue="253" us="253"/><bf gi="285" ue="254" us="254"/><bf gi="221" ue="255" us="255"/><bf gi="1889" ue="256" us="256"/><bf gi="2229" ue="257" us="257"/><bf gi="1890" ue="258" us="258"/><bf gi="2230" ue="259" us="259"/><bf gi="225" ue="260" us="260"/><bf gi="237" ue="261" us="261"/><bf gi="1947" ue="262" us="262"/><bf gi="2263" ue="263" us="263"/><bf gi="1948" ue="264" us="264"/><bf gi="2264" ue="265" us="265"/><bf gi="1950" ue="266" us="266"/><bf gi="2266" ue="267" us="267"/><bf gi="1949" ue="268" us="268"/><bf gi="2265" ue="269" us="269"/><bf gi="1955" ue="270" us="270"/><bf gi="242" ue="271" us="271"/><bf gi="1962" ue="272" us="272"/><bf gi="243" ue="273" us="273"/><bf gi="1965" ue="274" us="274"/><bf gi="2279" ue="275" us="275"/><bf gi="1966" ue="276" us="276"/><bf gi="2280" ue="277" us="277"/><bf gi="1967" ue="278" us="278"/><bf gi="2281" ue="279" us="279"/><bf gi="227" ue="280" us="280"/><bf gi="245" ue="281" us="281"/><bf gi="1964" ue="282" us="282"/><bf gi="2278" ue="283" us="283"/><bf gi="2000" ue="284" us="284"/><bf gi="2322" ue="285" us="285"/><bf gi="2001" ue="286" us="286"/><bf gi="2323" ue="287" us="287"/><bf gi="2002" ue="288" us="288"/><bf gi="2324" ue="289" us="289"/><bf gi="2003" ue="290" us="290"/><bf gi="2325" ue="291" us="291"/><bf gi="2007" ue="292" us="292"/><bf gi="276" ue="29Line truncated
Binary file not shown.
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Lato-HairlineItalic</font-name><full-name>Lato Hairline Italic</full-name><family-name>Lato</family-name><embed/><cap-height>700</cap-height><x-height>490</x-height><ascender>805</ascender><descender>-195</descender><bbox><left>-459</left><bottom>-259</bottom><right>1286</right><top>1034</top></bbox><flags>97</flags><stemv>0</stemv><italicangle>-7</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="1" ue="0" us="0"/><bf gi="169" ue="13" us="13"/><bf gi="2" ue="32" us="32"/><bf gi="81" ue="33" us="33"/><bf gi="120" ue="34" us="34"/><bf gi="132" ue="35" us="35"/><bf gi="128" ue="36" us="36"/><bf gi="164" ue="37" us="37"/><bf gi="121" ue="38" us="38"/><bf gi="119" ue="39" us="39"/><bf gi="106" ue="41" us="40"/><bf gi="112" ue="42" us="42"/><bf gi="142" ue="43" us="43"/><bf gi="83" ue="44" us="44"/><bf gi="100" ue="45" us="45"/><bf gi="85" ue="46" us="46"/><bf gi="97" ue="47" us="47"/><bf gi="133" ue="53" us="48"/><bf gi="162" ue="54" us="54"/><bf gi="139" ue="55" us="55"/><bf gi="163" ue="56" us="56"/><bf gi="140" ue="57" us="57"/><bf gi="170" ue="58" us="58"/><bf gi="84" ue="59" us="59"/><bf gi="147" ue="60" us="60"/><bf gi="144" ue="61" us="61"/><bf gi="148" ue="62" us="62"/><bf gi="82" ue="63" us="63"/><bf gi="122" ue="64" us="64"/><bf gi="3" ue="65" us="65"/><bf gi="5" ue="67" us="66"/><bf gi="8" ue="79" us="68"/><bf gi="22" ue="90" us="80"/><bf gi="108" ue="91" us="91"/><bf gi="99" ue="92" us="92"/><bf gi="109" ue="93" us="93"/><bf gi="117" ue="94" us="94"/><bf gi="103" ue="95" us="95"/><bf gi="68" ue="96" us="96"/><bf gi="33" ue="97" us="97"/><bf gi="35" ue="99" us="98"/><bf gi="38" ue="102" us="100"/><bf gi="43" ue="105" us="103"/><bf gi="47" ue="107" us="106"/><bf gi="161" ue="108" us="108"/><bf gi="49" ue="111" us="109"/><bf gi="54" ue="115" us="112"/><bf gi="59" ue="122" us="116"/><bf gi="110" ue="123" us="123"/><bf gi="98" ue="124" us="124"/><bf gi="111" ue="125" us="125"/><bf gi="118" ue="126" us="126"/><bf gi="2" ue="160" us="160"/><bf gi="165" ue="161" us="161"/><bf gi="129" ue="163" us="162"/><bf gi="455" ue="164" us="164"/><bf gi="131" ue="165" us="165"/><bf gi="452" ue="166" us="166"/><bf gi="115" ue="167" us="167"/><bf gi="171" ue="168" us="168"/><bf gi="123" ue="169" us="169"/><bf gi="66" ue="170" us="170"/><bf gi="95" ue="171" us="171"/><bf gi="152" ue="172" us="172"/><bf gi="100" ue="173" us="173"/><bf gi="124" ue="174" us="174"/><bf gi="73" ue="175" us="175"/><bf gi="126" ue="176" us="176"/><bf gi="149" ue="177" us="177"/><bf gi="1202" ue="179" us="178"/><bf gi="69" ue="180" us="180"/><bf gi="224" ue="181" us="181"/><bf gi="116" ue="182" us="182"/><bf gi="105" ue="183" us="183"/><bf gi="78" ue="184" us="184"/><bf gi="1204" ue="185" us="185"/><bf gi="67" ue="186" us="186"/><bf gi="96" ue="187" us="187"/><bf gi="1205" ue="190" us="188"/><bf gi="166" ue="191" us="191"/><bf gi="172" ue="197" us="192"/><bf gi="4" ue="198" us="198"/><bf gi="7" ue="199" us="199"/><bf gi="178" ue="207" us="200"/><bf gi="226" ue="208" us="208"/><bf gi="186" ue="214" us="209"/><bf gi="517" ue="215" us="215"/><bf gi="20" ue="216" us="216"/><bf gi="192" ue="220" us="217"/><bf gi="1973" ue="221" us="221"/><bf gi="233" ue="222" us="222"/><bf gi="58" ue="223" us="223"/><bf gi="197" ue="229" us="224"/><bf gi="34" ue="230" us="230"/><bf gi="37" ue="231" us="231"/><bf gi="203" ue="239" us="232"/><bf gi="244" ue="240" us="240"/><bf gi="211" ue="246" us="241"/><bf gi="143" ue="247" us="247"/><bf gi="52" ue="248" us="248"/><bf gi="217" ue="252" us="249"/><bf gi="2312" ue="253" us="253"/><bf gi="285" ue="254" us="254"/><bf gi="221" ue="255" us="255"/><bf gi="1659" ue="256" us="256"/><bf gi="1999" ue="257" us="257"/><bf gi="1660" ue="258" us="258"/><bf gi="2000" ue="259" us="259"/><bf gi="225" ue="260" us="260"/><bf gi="237" ue="261" us="261"/><bf gi="1717" ue="262" us="262"/><bf gi="2033" ue="263" us="263"/><bf gi="1718" ue="264" us="264"/><bf gi="2034" ue="265" us="265"/><bf gi="1720" ue="266" us="266"/><bf gi="2036" ue="267" us="267"/><bf gi="1719" ue="268" us="268"/><bf gi="2035" ue="269" us="269"/><bf gi="1725" ue="270" us="270"/><bf gi="242" ue="271" us="271"/><bf gi="1732" ue="272" us="272"/><bf gi="243" ue="273" us="273"/><bf gi="1735" ue="274" us="274"/><bf gi="2049" ue="275" us="275"/><bf gi="1736" ue="276" us="276"/><bf gi="2050" ue="277" us="277"/><bf gi="1737" ue="278" us="278"/><bf gi="2051" ue="279" us="279"/><bf gi="227" ue="280" us="280"/><bf gi="245" ue="281" us="281"/><bf gi="1734" ue="282" us="282"/><bf gi="2048" ue="283" us="283"/><bf gi="1770" ue="284" us="284"/><bf gi="2092" ue="285" us="285"/><bf gi="1771" ue="286" us="286"/><bf gi="2093" ue="287" us="287"/><bf gi="1772" ue="288" us="288"/><bf gi="2094" ue="289" us="289"/><bf gi="1773" ue="290" us="290"/><bf gi="2095" ue="291" us="291"/><bf gi="1777" ue="292" us="292"/><bf gLine truncated
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Lato-Heavy</font-name><full-name>Lato Heavy</full-name><family-name>Lato</family-name><embed/><cap-height>725</cap-height><x-height>515</x-height><ascender>805</ascender><descender>-195</descender><bbox><left>-626</left><bottom>-291</bottom><right>1345</right><top>1107</top></bbox><flags>33</flags><stemv>0</stemv><italicangle>0</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="1" ue="0" us="0"/><bf gi="171" ue="13" us="13"/><bf gi="2" ue="32" us="32"/><bf gi="82" ue="33" us="33"/><bf gi="122" ue="34" us="34"/><bf gi="134" ue="35" us="35"/><bf gi="130" ue="36" us="36"/><bf gi="166" ue="37" us="37"/><bf gi="123" ue="38" us="38"/><bf gi="121" ue="39" us="39"/><bf gi="108" ue="41" us="40"/><bf gi="114" ue="42" us="42"/><bf gi="144" ue="43" us="43"/><bf gi="84" ue="44" us="44"/><bf gi="102" ue="45" us="45"/><bf gi="87" ue="46" us="46"/><bf gi="99" ue="47" us="47"/><bf gi="135" ue="53" us="48"/><bf gi="164" ue="54" us="54"/><bf gi="141" ue="55" us="55"/><bf gi="165" ue="56" us="56"/><bf gi="142" ue="57" us="57"/><bf gi="86" ue="58" us="58"/><bf gi="85" ue="59" us="59"/><bf gi="149" ue="60" us="60"/><bf gi="146" ue="61" us="61"/><bf gi="150" ue="62" us="62"/><bf gi="83" ue="63" us="63"/><bf gi="124" ue="64" us="64"/><bf gi="3" ue="65" us="65"/><bf gi="5" ue="67" us="66"/><bf gi="8" ue="79" us="68"/><bf gi="22" ue="90" us="80"/><bf gi="110" ue="91" us="91"/><bf gi="101" ue="92" us="92"/><bf gi="111" ue="93" us="93"/><bf gi="119" ue="94" us="94"/><bf gi="105" ue="95" us="95"/><bf gi="68" ue="96" us="96"/><bf gi="33" ue="97" us="97"/><bf gi="35" ue="99" us="98"/><bf gi="38" ue="102" us="100"/><bf gi="43" ue="105" us="103"/><bf gi="47" ue="107" us="106"/><bf gi="163" ue="108" us="108"/><bf gi="49" ue="111" us="109"/><bf gi="54" ue="115" us="112"/><bf gi="59" ue="122" us="116"/><bf gi="112" ue="123" us="123"/><bf gi="100" ue="124" us="124"/><bf gi="113" ue="125" us="125"/><bf gi="120" ue="126" us="126"/><bf gi="2" ue="160" us="160"/><bf gi="167" ue="161" us="161"/><bf gi="131" ue="163" us="162"/><bf gi="455" ue="164" us="164"/><bf gi="133" ue="165" us="165"/><bf gi="452" ue="166" us="166"/><bf gi="117" ue="167" us="167"/><bf gi="73" ue="168" us="168"/><bf gi="125" ue="169" us="169"/><bf gi="66" ue="170" us="170"/><bf gi="97" ue="171" us="171"/><bf gi="154" ue="172" us="172"/><bf gi="102" ue="173" us="173"/><bf gi="126" ue="174" us="174"/><bf gi="74" ue="175" us="175"/><bf gi="128" ue="176" us="176"/><bf gi="151" ue="177" us="177"/><bf gi="1202" ue="179" us="178"/><bf gi="69" ue="180" us="180"/><bf gi="224" ue="181" us="181"/><bf gi="118" ue="182" us="182"/><bf gi="107" ue="183" us="183"/><bf gi="79" ue="184" us="184"/><bf gi="1204" ue="185" us="185"/><bf gi="67" ue="186" us="186"/><bf gi="98" ue="187" us="187"/><bf gi="1205" ue="190" us="188"/><bf gi="168" ue="191" us="191"/><bf gi="172" ue="197" us="192"/><bf gi="4" ue="198" us="198"/><bf gi="7" ue="199" us="199"/><bf gi="178" ue="207" us="200"/><bf gi="226" ue="208" us="208"/><bf gi="186" ue="214" us="209"/><bf gi="517" ue="215" us="215"/><bf gi="20" ue="216" us="216"/><bf gi="192" ue="220" us="217"/><bf gi="2203" ue="221" us="221"/><bf gi="233" ue="222" us="222"/><bf gi="58" ue="223" us="223"/><bf gi="197" ue="229" us="224"/><bf gi="34" ue="230" us="230"/><bf gi="37" ue="231" us="231"/><bf gi="203" ue="239" us="232"/><bf gi="244" ue="240" us="240"/><bf gi="211" ue="246" us="241"/><bf gi="145" ue="247" us="247"/><bf gi="52" ue="248" us="248"/><bf gi="217" ue="252" us="249"/><bf gi="2538" ue="253" us="253"/><bf gi="285" ue="254" us="254"/><bf gi="221" ue="255" us="255"/><bf gi="1889" ue="256" us="256"/><bf gi="2229" ue="257" us="257"/><bf gi="1890" ue="258" us="258"/><bf gi="2230" ue="259" us="259"/><bf gi="225" ue="260" us="260"/><bf gi="237" ue="261" us="261"/><bf gi="1947" ue="262" us="262"/><bf gi="2263" ue="263" us="263"/><bf gi="1948" ue="264" us="264"/><bf gi="2264" ue="265" us="265"/><bf gi="1950" ue="266" us="266"/><bf gi="2266" ue="267" us="267"/><bf gi="1949" ue="268" us="268"/><bf gi="2265" ue="269" us="269"/><bf gi="1955" ue="270" us="270"/><bf gi="242" ue="271" us="271"/><bf gi="1962" ue="272" us="272"/><bf gi="243" ue="273" us="273"/><bf gi="1965" ue="274" us="274"/><bf gi="2279" ue="275" us="275"/><bf gi="1966" ue="276" us="276"/><bf gi="2280" ue="277" us="277"/><bf gi="1967" ue="278" us="278"/><bf gi="2281" ue="279" us="279"/><bf gi="227" ue="280" us="280"/><bf gi="245" ue="281" us="281"/><bf gi="1964" ue="282" us="282"/><bf gi="2278" ue="283" us="283"/><bf gi="2000" ue="284" us="284"/><bf gi="2322" ue="285" us="285"/><bf gi="2001" ue="286" us="286"/><bf gi="2323" ue="287" us="287"/><bf gi="2002" ue="288" us="288"/><bf gi="2324" ue="289" us="289"/><bf gi="2003" ue="290" us="290"/><bf gi="2325" ue="291" us="291"/><bf gi="2007" ue="292" us="292"/><bf gi="276" ue="293" us=Line truncated
Binary file not shown.
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Lato-HeavyItalic</font-name><full-name>Lato Heavy Italic</full-name><family-name>Lato</family-name><embed/><cap-height>725</cap-height><x-height>515</x-height><ascender>805</ascender><descender>-195</descender><bbox><left>-528</left><bottom>-289</bottom><right>1294</right><top>1105</top></bbox><flags>97</flags><stemv>0</stemv><italicangle>-7</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="1" ue="0" us="0"/><bf gi="169" ue="13" us="13"/><bf gi="2" ue="32" us="32"/><bf gi="81" ue="33" us="33"/><bf gi="120" ue="34" us="34"/><bf gi="132" ue="35" us="35"/><bf gi="128" ue="36" us="36"/><bf gi="164" ue="37" us="37"/><bf gi="121" ue="38" us="38"/><bf gi="119" ue="39" us="39"/><bf gi="106" ue="41" us="40"/><bf gi="112" ue="42" us="42"/><bf gi="142" ue="43" us="43"/><bf gi="83" ue="44" us="44"/><bf gi="100" ue="45" us="45"/><bf gi="85" ue="46" us="46"/><bf gi="97" ue="47" us="47"/><bf gi="133" ue="53" us="48"/><bf gi="162" ue="54" us="54"/><bf gi="139" ue="55" us="55"/><bf gi="163" ue="56" us="56"/><bf gi="140" ue="57" us="57"/><bf gi="170" ue="58" us="58"/><bf gi="84" ue="59" us="59"/><bf gi="147" ue="60" us="60"/><bf gi="144" ue="61" us="61"/><bf gi="148" ue="62" us="62"/><bf gi="82" ue="63" us="63"/><bf gi="122" ue="64" us="64"/><bf gi="3" ue="65" us="65"/><bf gi="5" ue="67" us="66"/><bf gi="8" ue="79" us="68"/><bf gi="22" ue="90" us="80"/><bf gi="108" ue="91" us="91"/><bf gi="99" ue="92" us="92"/><bf gi="109" ue="93" us="93"/><bf gi="117" ue="94" us="94"/><bf gi="103" ue="95" us="95"/><bf gi="68" ue="96" us="96"/><bf gi="33" ue="97" us="97"/><bf gi="35" ue="99" us="98"/><bf gi="38" ue="102" us="100"/><bf gi="43" ue="105" us="103"/><bf gi="47" ue="107" us="106"/><bf gi="161" ue="108" us="108"/><bf gi="49" ue="111" us="109"/><bf gi="54" ue="115" us="112"/><bf gi="59" ue="122" us="116"/><bf gi="110" ue="123" us="123"/><bf gi="98" ue="124" us="124"/><bf gi="111" ue="125" us="125"/><bf gi="118" ue="126" us="126"/><bf gi="2" ue="160" us="160"/><bf gi="165" ue="161" us="161"/><bf gi="129" ue="163" us="162"/><bf gi="455" ue="164" us="164"/><bf gi="131" ue="165" us="165"/><bf gi="452" ue="166" us="166"/><bf gi="115" ue="167" us="167"/><bf gi="171" ue="168" us="168"/><bf gi="123" ue="169" us="169"/><bf gi="66" ue="170" us="170"/><bf gi="95" ue="171" us="171"/><bf gi="152" ue="172" us="172"/><bf gi="100" ue="173" us="173"/><bf gi="124" ue="174" us="174"/><bf gi="73" ue="175" us="175"/><bf gi="126" ue="176" us="176"/><bf gi="149" ue="177" us="177"/><bf gi="1202" ue="179" us="178"/><bf gi="69" ue="180" us="180"/><bf gi="224" ue="181" us="181"/><bf gi="116" ue="182" us="182"/><bf gi="105" ue="183" us="183"/><bf gi="78" ue="184" us="184"/><bf gi="1204" ue="185" us="185"/><bf gi="67" ue="186" us="186"/><bf gi="96" ue="187" us="187"/><bf gi="1205" ue="190" us="188"/><bf gi="166" ue="191" us="191"/><bf gi="172" ue="197" us="192"/><bf gi="4" ue="198" us="198"/><bf gi="7" ue="199" us="199"/><bf gi="178" ue="207" us="200"/><bf gi="226" ue="208" us="208"/><bf gi="186" ue="214" us="209"/><bf gi="517" ue="215" us="215"/><bf gi="20" ue="216" us="216"/><bf gi="192" ue="220" us="217"/><bf gi="1973" ue="221" us="221"/><bf gi="233" ue="222" us="222"/><bf gi="58" ue="223" us="223"/><bf gi="197" ue="229" us="224"/><bf gi="34" ue="230" us="230"/><bf gi="37" ue="231" us="231"/><bf gi="203" ue="239" us="232"/><bf gi="244" ue="240" us="240"/><bf gi="211" ue="246" us="241"/><bf gi="143" ue="247" us="247"/><bf gi="52" ue="248" us="248"/><bf gi="217" ue="252" us="249"/><bf gi="2312" ue="253" us="253"/><bf gi="285" ue="254" us="254"/><bf gi="221" ue="255" us="255"/><bf gi="1659" ue="256" us="256"/><bf gi="1999" ue="257" us="257"/><bf gi="1660" ue="258" us="258"/><bf gi="2000" ue="259" us="259"/><bf gi="225" ue="260" us="260"/><bf gi="237" ue="261" us="261"/><bf gi="1717" ue="262" us="262"/><bf gi="2033" ue="263" us="263"/><bf gi="1718" ue="264" us="264"/><bf gi="2034" ue="265" us="265"/><bf gi="1720" ue="266" us="266"/><bf gi="2036" ue="267" us="267"/><bf gi="1719" ue="268" us="268"/><bf gi="2035" ue="269" us="269"/><bf gi="1725" ue="270" us="270"/><bf gi="242" ue="271" us="271"/><bf gi="1732" ue="272" us="272"/><bf gi="243" ue="273" us="273"/><bf gi="1735" ue="274" us="274"/><bf gi="2049" ue="275" us="275"/><bf gi="1736" ue="276" us="276"/><bf gi="2050" ue="277" us="277"/><bf gi="1737" ue="278" us="278"/><bf gi="2051" ue="279" us="279"/><bf gi="227" ue="280" us="280"/><bf gi="245" ue="281" us="281"/><bf gi="1734" ue="282" us="282"/><bf gi="2048" ue="283" us="283"/><bf gi="1770" ue="284" us="284"/><bf gi="2092" ue="285" us="285"/><bf gi="1771" ue="286" us="286"/><bf gi="2093" ue="287" us="287"/><bf gi="1772" ue="288" us="288"/><bf gi="2094" ue="289" us="289"/><bf gi="1773" ue="290" us="290"/><bf gi="2095" ue="291" us="291"/><bf gi="1777" ue="292" us="292"/><bf gi="276Line truncated
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Lato-Italic</font-name><full-name>Lato Italic</full-name><family-name>Lato</family-name><embed/><cap-height>716</cap-height><x-height>506</x-height><ascender>805</ascender><descender>-195</descender><bbox><left>-501</left><bottom>-268</bottom><right>1290</right><top>1077</top></bbox><flags>97</flags><stemv>0</stemv><italicangle>-7</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="1" ue="0" us="0"/><bf gi="169" ue="13" us="13"/><bf gi="2" ue="32" us="32"/><bf gi="81" ue="33" us="33"/><bf gi="120" ue="34" us="34"/><bf gi="132" ue="35" us="35"/><bf gi="128" ue="36" us="36"/><bf gi="164" ue="37" us="37"/><bf gi="121" ue="38" us="38"/><bf gi="119" ue="39" us="39"/><bf gi="106" ue="41" us="40"/><bf gi="112" ue="42" us="42"/><bf gi="142" ue="43" us="43"/><bf gi="83" ue="44" us="44"/><bf gi="100" ue="45" us="45"/><bf gi="85" ue="46" us="46"/><bf gi="97" ue="47" us="47"/><bf gi="133" ue="53" us="48"/><bf gi="162" ue="54" us="54"/><bf gi="139" ue="55" us="55"/><bf gi="163" ue="56" us="56"/><bf gi="140" ue="57" us="57"/><bf gi="170" ue="58" us="58"/><bf gi="84" ue="59" us="59"/><bf gi="147" ue="60" us="60"/><bf gi="144" ue="61" us="61"/><bf gi="148" ue="62" us="62"/><bf gi="82" ue="63" us="63"/><bf gi="122" ue="64" us="64"/><bf gi="3" ue="65" us="65"/><bf gi="5" ue="67" us="66"/><bf gi="8" ue="79" us="68"/><bf gi="22" ue="90" us="80"/><bf gi="108" ue="91" us="91"/><bf gi="99" ue="92" us="92"/><bf gi="109" ue="93" us="93"/><bf gi="117" ue="94" us="94"/><bf gi="103" ue="95" us="95"/><bf gi="68" ue="96" us="96"/><bf gi="33" ue="97" us="97"/><bf gi="35" ue="99" us="98"/><bf gi="38" ue="102" us="100"/><bf gi="43" ue="105" us="103"/><bf gi="47" ue="107" us="106"/><bf gi="161" ue="108" us="108"/><bf gi="49" ue="111" us="109"/><bf gi="54" ue="115" us="112"/><bf gi="59" ue="122" us="116"/><bf gi="110" ue="123" us="123"/><bf gi="98" ue="124" us="124"/><bf gi="111" ue="125" us="125"/><bf gi="118" ue="126" us="126"/><bf gi="2" ue="160" us="160"/><bf gi="165" ue="161" us="161"/><bf gi="129" ue="163" us="162"/><bf gi="455" ue="164" us="164"/><bf gi="131" ue="165" us="165"/><bf gi="452" ue="166" us="166"/><bf gi="115" ue="167" us="167"/><bf gi="171" ue="168" us="168"/><bf gi="123" ue="169" us="169"/><bf gi="66" ue="170" us="170"/><bf gi="95" ue="171" us="171"/><bf gi="152" ue="172" us="172"/><bf gi="100" ue="173" us="173"/><bf gi="124" ue="174" us="174"/><bf gi="73" ue="175" us="175"/><bf gi="126" ue="176" us="176"/><bf gi="149" ue="177" us="177"/><bf gi="1202" ue="179" us="178"/><bf gi="69" ue="180" us="180"/><bf gi="224" ue="181" us="181"/><bf gi="116" ue="182" us="182"/><bf gi="105" ue="183" us="183"/><bf gi="78" ue="184" us="184"/><bf gi="1204" ue="185" us="185"/><bf gi="67" ue="186" us="186"/><bf gi="96" ue="187" us="187"/><bf gi="1205" ue="190" us="188"/><bf gi="166" ue="191" us="191"/><bf gi="172" ue="197" us="192"/><bf gi="4" ue="198" us="198"/><bf gi="7" ue="199" us="199"/><bf gi="178" ue="207" us="200"/><bf gi="226" ue="208" us="208"/><bf gi="186" ue="214" us="209"/><bf gi="517" ue="215" us="215"/><bf gi="20" ue="216" us="216"/><bf gi="192" ue="220" us="217"/><bf gi="1973" ue="221" us="221"/><bf gi="233" ue="222" us="222"/><bf gi="58" ue="223" us="223"/><bf gi="197" ue="229" us="224"/><bf gi="34" ue="230" us="230"/><bf gi="37" ue="231" us="231"/><bf gi="203" ue="239" us="232"/><bf gi="244" ue="240" us="240"/><bf gi="211" ue="246" us="241"/><bf gi="143" ue="247" us="247"/><bf gi="52" ue="248" us="248"/><bf gi="217" ue="252" us="249"/><bf gi="2312" ue="253" us="253"/><bf gi="285" ue="254" us="254"/><bf gi="221" ue="255" us="255"/><bf gi="1659" ue="256" us="256"/><bf gi="1999" ue="257" us="257"/><bf gi="1660" ue="258" us="258"/><bf gi="2000" ue="259" us="259"/><bf gi="225" ue="260" us="260"/><bf gi="237" ue="261" us="261"/><bf gi="1717" ue="262" us="262"/><bf gi="2033" ue="263" us="263"/><bf gi="1718" ue="264" us="264"/><bf gi="2034" ue="265" us="265"/><bf gi="1720" ue="266" us="266"/><bf gi="2036" ue="267" us="267"/><bf gi="1719" ue="268" us="268"/><bf gi="2035" ue="269" us="269"/><bf gi="1725" ue="270" us="270"/><bf gi="242" ue="271" us="271"/><bf gi="1732" ue="272" us="272"/><bf gi="243" ue="273" us="273"/><bf gi="1735" ue="274" us="274"/><bf gi="2049" ue="275" us="275"/><bf gi="1736" ue="276" us="276"/><bf gi="2050" ue="277" us="277"/><bf gi="1737" ue="278" us="278"/><bf gi="2051" ue="279" us="279"/><bf gi="227" ue="280" us="280"/><bf gi="245" ue="281" us="281"/><bf gi="1734" ue="282" us="282"/><bf gi="2048" ue="283" us="283"/><bf gi="1770" ue="284" us="284"/><bf gi="2092" ue="285" us="285"/><bf gi="1771" ue="286" us="286"/><bf gi="2093" ue="287" us="287"/><bf gi="1772" ue="288" us="288"/><bf gi="2094" ue="289" us="289"/><bf gi="1773" ue="290" us="290"/><bf gi="2095" ue="291" us="291"/><bf gi="1777" ue="292" us="292"/><bf gi="276" ue="293" Line truncated
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Lato-Light</font-name><full-name>Lato Light</full-name><family-name>Lato</family-name><embed/><cap-height>707</cap-height><x-height>497</x-height><ascender>805</ascender><descender>-195</descender><bbox><left>-479</left><bottom>-263</bottom><right>1341</right><top>1055</top></bbox><flags>33</flags><stemv>0</stemv><italicangle>0</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="1" ue="0" us="0"/><bf gi="171" ue="13" us="13"/><bf gi="2" ue="32" us="32"/><bf gi="82" ue="33" us="33"/><bf gi="122" ue="34" us="34"/><bf gi="134" ue="35" us="35"/><bf gi="130" ue="36" us="36"/><bf gi="166" ue="37" us="37"/><bf gi="123" ue="38" us="38"/><bf gi="121" ue="39" us="39"/><bf gi="108" ue="41" us="40"/><bf gi="114" ue="42" us="42"/><bf gi="144" ue="43" us="43"/><bf gi="84" ue="44" us="44"/><bf gi="102" ue="45" us="45"/><bf gi="87" ue="46" us="46"/><bf gi="99" ue="47" us="47"/><bf gi="135" ue="53" us="48"/><bf gi="164" ue="54" us="54"/><bf gi="141" ue="55" us="55"/><bf gi="165" ue="56" us="56"/><bf gi="142" ue="57" us="57"/><bf gi="86" ue="58" us="58"/><bf gi="85" ue="59" us="59"/><bf gi="149" ue="60" us="60"/><bf gi="146" ue="61" us="61"/><bf gi="150" ue="62" us="62"/><bf gi="83" ue="63" us="63"/><bf gi="124" ue="64" us="64"/><bf gi="3" ue="65" us="65"/><bf gi="5" ue="67" us="66"/><bf gi="8" ue="79" us="68"/><bf gi="22" ue="90" us="80"/><bf gi="110" ue="91" us="91"/><bf gi="101" ue="92" us="92"/><bf gi="111" ue="93" us="93"/><bf gi="119" ue="94" us="94"/><bf gi="105" ue="95" us="95"/><bf gi="68" ue="96" us="96"/><bf gi="33" ue="97" us="97"/><bf gi="35" ue="99" us="98"/><bf gi="38" ue="102" us="100"/><bf gi="43" ue="105" us="103"/><bf gi="47" ue="107" us="106"/><bf gi="163" ue="108" us="108"/><bf gi="49" ue="111" us="109"/><bf gi="54" ue="115" us="112"/><bf gi="59" ue="122" us="116"/><bf gi="112" ue="123" us="123"/><bf gi="100" ue="124" us="124"/><bf gi="113" ue="125" us="125"/><bf gi="120" ue="126" us="126"/><bf gi="2" ue="160" us="160"/><bf gi="167" ue="161" us="161"/><bf gi="131" ue="163" us="162"/><bf gi="455" ue="164" us="164"/><bf gi="133" ue="165" us="165"/><bf gi="452" ue="166" us="166"/><bf gi="117" ue="167" us="167"/><bf gi="73" ue="168" us="168"/><bf gi="125" ue="169" us="169"/><bf gi="66" ue="170" us="170"/><bf gi="97" ue="171" us="171"/><bf gi="154" ue="172" us="172"/><bf gi="102" ue="173" us="173"/><bf gi="126" ue="174" us="174"/><bf gi="74" ue="175" us="175"/><bf gi="128" ue="176" us="176"/><bf gi="151" ue="177" us="177"/><bf gi="1202" ue="179" us="178"/><bf gi="69" ue="180" us="180"/><bf gi="224" ue="181" us="181"/><bf gi="118" ue="182" us="182"/><bf gi="107" ue="183" us="183"/><bf gi="79" ue="184" us="184"/><bf gi="1204" ue="185" us="185"/><bf gi="67" ue="186" us="186"/><bf gi="98" ue="187" us="187"/><bf gi="1205" ue="190" us="188"/><bf gi="168" ue="191" us="191"/><bf gi="172" ue="197" us="192"/><bf gi="4" ue="198" us="198"/><bf gi="7" ue="199" us="199"/><bf gi="178" ue="207" us="200"/><bf gi="226" ue="208" us="208"/><bf gi="186" ue="214" us="209"/><bf gi="517" ue="215" us="215"/><bf gi="20" ue="216" us="216"/><bf gi="192" ue="220" us="217"/><bf gi="2203" ue="221" us="221"/><bf gi="233" ue="222" us="222"/><bf gi="58" ue="223" us="223"/><bf gi="197" ue="229" us="224"/><bf gi="34" ue="230" us="230"/><bf gi="37" ue="231" us="231"/><bf gi="203" ue="239" us="232"/><bf gi="244" ue="240" us="240"/><bf gi="211" ue="246" us="241"/><bf gi="145" ue="247" us="247"/><bf gi="52" ue="248" us="248"/><bf gi="217" ue="252" us="249"/><bf gi="2538" ue="253" us="253"/><bf gi="285" ue="254" us="254"/><bf gi="221" ue="255" us="255"/><bf gi="1889" ue="256" us="256"/><bf gi="2229" ue="257" us="257"/><bf gi="1890" ue="258" us="258"/><bf gi="2230" ue="259" us="259"/><bf gi="225" ue="260" us="260"/><bf gi="237" ue="261" us="261"/><bf gi="1947" ue="262" us="262"/><bf gi="2263" ue="263" us="263"/><bf gi="1948" ue="264" us="264"/><bf gi="2264" ue="265" us="265"/><bf gi="1950" ue="266" us="266"/><bf gi="2266" ue="267" us="267"/><bf gi="1949" ue="268" us="268"/><bf gi="2265" ue="269" us="269"/><bf gi="1955" ue="270" us="270"/><bf gi="242" ue="271" us="271"/><bf gi="1962" ue="272" us="272"/><bf gi="243" ue="273" us="273"/><bf gi="1965" ue="274" us="274"/><bf gi="2279" ue="275" us="275"/><bf gi="1966" ue="276" us="276"/><bf gi="2280" ue="277" us="277"/><bf gi="1967" ue="278" us="278"/><bf gi="2281" ue="279" us="279"/><bf gi="227" ue="280" us="280"/><bf gi="245" ue="281" us="281"/><bf gi="1964" ue="282" us="282"/><bf gi="2278" ue="283" us="283"/><bf gi="2000" ue="284" us="284"/><bf gi="2322" ue="285" us="285"/><bf gi="2001" ue="286" us="286"/><bf gi="2323" ue="287" us="287"/><bf gi="2002" ue="288" us="288"/><bf gi="2324" ue="289" us="289"/><bf gi="2003" ue="290" us="290"/><bf gi="2325" ue="291" us="291"/><bf gi="2007" ue="292" us="292"/><bf gi="276" ue="293" us=Line truncated
Binary file not shown.
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Lato-LightItalic</font-name><full-name>Lato Light Italic</full-name><family-name>Lato</family-name><embed/><cap-height>707</cap-height><x-height>497</x-height><ascender>805</ascender><descender>-195</descender><bbox><left>-479</left><bottom>-263</bottom><right>1288</right><top>1054</top></bbox><flags>97</flags><stemv>0</stemv><italicangle>-7</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="1" ue="0" us="0"/><bf gi="169" ue="13" us="13"/><bf gi="2" ue="32" us="32"/><bf gi="81" ue="33" us="33"/><bf gi="120" ue="34" us="34"/><bf gi="132" ue="35" us="35"/><bf gi="128" ue="36" us="36"/><bf gi="164" ue="37" us="37"/><bf gi="121" ue="38" us="38"/><bf gi="119" ue="39" us="39"/><bf gi="106" ue="41" us="40"/><bf gi="112" ue="42" us="42"/><bf gi="142" ue="43" us="43"/><bf gi="83" ue="44" us="44"/><bf gi="100" ue="45" us="45"/><bf gi="85" ue="46" us="46"/><bf gi="97" ue="47" us="47"/><bf gi="133" ue="53" us="48"/><bf gi="162" ue="54" us="54"/><bf gi="139" ue="55" us="55"/><bf gi="163" ue="56" us="56"/><bf gi="140" ue="57" us="57"/><bf gi="170" ue="58" us="58"/><bf gi="84" ue="59" us="59"/><bf gi="147" ue="60" us="60"/><bf gi="144" ue="61" us="61"/><bf gi="148" ue="62" us="62"/><bf gi="82" ue="63" us="63"/><bf gi="122" ue="64" us="64"/><bf gi="3" ue="65" us="65"/><bf gi="5" ue="67" us="66"/><bf gi="8" ue="79" us="68"/><bf gi="22" ue="90" us="80"/><bf gi="108" ue="91" us="91"/><bf gi="99" ue="92" us="92"/><bf gi="109" ue="93" us="93"/><bf gi="117" ue="94" us="94"/><bf gi="103" ue="95" us="95"/><bf gi="68" ue="96" us="96"/><bf gi="33" ue="97" us="97"/><bf gi="35" ue="99" us="98"/><bf gi="38" ue="102" us="100"/><bf gi="43" ue="105" us="103"/><bf gi="47" ue="107" us="106"/><bf gi="161" ue="108" us="108"/><bf gi="49" ue="111" us="109"/><bf gi="54" ue="115" us="112"/><bf gi="59" ue="122" us="116"/><bf gi="110" ue="123" us="123"/><bf gi="98" ue="124" us="124"/><bf gi="111" ue="125" us="125"/><bf gi="118" ue="126" us="126"/><bf gi="2" ue="160" us="160"/><bf gi="165" ue="161" us="161"/><bf gi="129" ue="163" us="162"/><bf gi="455" ue="164" us="164"/><bf gi="131" ue="165" us="165"/><bf gi="452" ue="166" us="166"/><bf gi="115" ue="167" us="167"/><bf gi="171" ue="168" us="168"/><bf gi="123" ue="169" us="169"/><bf gi="66" ue="170" us="170"/><bf gi="95" ue="171" us="171"/><bf gi="152" ue="172" us="172"/><bf gi="100" ue="173" us="173"/><bf gi="124" ue="174" us="174"/><bf gi="73" ue="175" us="175"/><bf gi="126" ue="176" us="176"/><bf gi="149" ue="177" us="177"/><bf gi="1202" ue="179" us="178"/><bf gi="69" ue="180" us="180"/><bf gi="224" ue="181" us="181"/><bf gi="116" ue="182" us="182"/><bf gi="105" ue="183" us="183"/><bf gi="78" ue="184" us="184"/><bf gi="1204" ue="185" us="185"/><bf gi="67" ue="186" us="186"/><bf gi="96" ue="187" us="187"/><bf gi="1205" ue="190" us="188"/><bf gi="166" ue="191" us="191"/><bf gi="172" ue="197" us="192"/><bf gi="4" ue="198" us="198"/><bf gi="7" ue="199" us="199"/><bf gi="178" ue="207" us="200"/><bf gi="226" ue="208" us="208"/><bf gi="186" ue="214" us="209"/><bf gi="517" ue="215" us="215"/><bf gi="20" ue="216" us="216"/><bf gi="192" ue="220" us="217"/><bf gi="1973" ue="221" us="221"/><bf gi="233" ue="222" us="222"/><bf gi="58" ue="223" us="223"/><bf gi="197" ue="229" us="224"/><bf gi="34" ue="230" us="230"/><bf gi="37" ue="231" us="231"/><bf gi="203" ue="239" us="232"/><bf gi="244" ue="240" us="240"/><bf gi="211" ue="246" us="241"/><bf gi="143" ue="247" us="247"/><bf gi="52" ue="248" us="248"/><bf gi="217" ue="252" us="249"/><bf gi="2312" ue="253" us="253"/><bf gi="285" ue="254" us="254"/><bf gi="221" ue="255" us="255"/><bf gi="1659" ue="256" us="256"/><bf gi="1999" ue="257" us="257"/><bf gi="1660" ue="258" us="258"/><bf gi="2000" ue="259" us="259"/><bf gi="225" ue="260" us="260"/><bf gi="237" ue="261" us="261"/><bf gi="1717" ue="262" us="262"/><bf gi="2033" ue="263" us="263"/><bf gi="1718" ue="264" us="264"/><bf gi="2034" ue="265" us="265"/><bf gi="1720" ue="266" us="266"/><bf gi="2036" ue="267" us="267"/><bf gi="1719" ue="268" us="268"/><bf gi="2035" ue="269" us="269"/><bf gi="1725" ue="270" us="270"/><bf gi="242" ue="271" us="271"/><bf gi="1732" ue="272" us="272"/><bf gi="243" ue="273" us="273"/><bf gi="1735" ue="274" us="274"/><bf gi="2049" ue="275" us="275"/><bf gi="1736" ue="276" us="276"/><bf gi="2050" ue="277" us="277"/><bf gi="1737" ue="278" us="278"/><bf gi="2051" ue="279" us="279"/><bf gi="227" ue="280" us="280"/><bf gi="245" ue="281" us="281"/><bf gi="1734" ue="282" us="282"/><bf gi="2048" ue="283" us="283"/><bf gi="1770" ue="284" us="284"/><bf gi="2092" ue="285" us="285"/><bf gi="1771" ue="286" us="286"/><bf gi="2093" ue="287" us="287"/><bf gi="1772" ue="288" us="288"/><bf gi="2094" ue="289" us="289"/><bf gi="1773" ue="290" us="290"/><bf gi="2095" ue="291" us="291"/><bf gi="1777" ue="292" us="292"/><bf gi="276Line truncated
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Lato-Medium</font-name><full-name>Lato Medium</full-name><family-name>Lato</family-name><embed/><cap-height>717</cap-height><x-height>507</x-height><ascender>805</ascender><descender>-195</descender><bbox><left>-556</left><bottom>-270</bottom><right>1343</right><top>1082</top></bbox><flags>33</flags><stemv>0</stemv><italicangle>0</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="1" ue="0" us="0"/><bf gi="171" ue="13" us="13"/><bf gi="2" ue="32" us="32"/><bf gi="82" ue="33" us="33"/><bf gi="122" ue="34" us="34"/><bf gi="134" ue="35" us="35"/><bf gi="130" ue="36" us="36"/><bf gi="166" ue="37" us="37"/><bf gi="123" ue="38" us="38"/><bf gi="121" ue="39" us="39"/><bf gi="108" ue="41" us="40"/><bf gi="114" ue="42" us="42"/><bf gi="144" ue="43" us="43"/><bf gi="84" ue="44" us="44"/><bf gi="102" ue="45" us="45"/><bf gi="87" ue="46" us="46"/><bf gi="99" ue="47" us="47"/><bf gi="135" ue="53" us="48"/><bf gi="164" ue="54" us="54"/><bf gi="141" ue="55" us="55"/><bf gi="165" ue="56" us="56"/><bf gi="142" ue="57" us="57"/><bf gi="86" ue="58" us="58"/><bf gi="85" ue="59" us="59"/><bf gi="149" ue="60" us="60"/><bf gi="146" ue="61" us="61"/><bf gi="150" ue="62" us="62"/><bf gi="83" ue="63" us="63"/><bf gi="124" ue="64" us="64"/><bf gi="3" ue="65" us="65"/><bf gi="5" ue="67" us="66"/><bf gi="8" ue="79" us="68"/><bf gi="22" ue="90" us="80"/><bf gi="110" ue="91" us="91"/><bf gi="101" ue="92" us="92"/><bf gi="111" ue="93" us="93"/><bf gi="119" ue="94" us="94"/><bf gi="105" ue="95" us="95"/><bf gi="68" ue="96" us="96"/><bf gi="33" ue="97" us="97"/><bf gi="35" ue="99" us="98"/><bf gi="38" ue="102" us="100"/><bf gi="43" ue="105" us="103"/><bf gi="47" ue="107" us="106"/><bf gi="163" ue="108" us="108"/><bf gi="49" ue="111" us="109"/><bf gi="54" ue="115" us="112"/><bf gi="59" ue="122" us="116"/><bf gi="112" ue="123" us="123"/><bf gi="100" ue="124" us="124"/><bf gi="113" ue="125" us="125"/><bf gi="120" ue="126" us="126"/><bf gi="2" ue="160" us="160"/><bf gi="167" ue="161" us="161"/><bf gi="131" ue="163" us="162"/><bf gi="455" ue="164" us="164"/><bf gi="133" ue="165" us="165"/><bf gi="452" ue="166" us="166"/><bf gi="117" ue="167" us="167"/><bf gi="73" ue="168" us="168"/><bf gi="125" ue="169" us="169"/><bf gi="66" ue="170" us="170"/><bf gi="97" ue="171" us="171"/><bf gi="154" ue="172" us="172"/><bf gi="102" ue="173" us="173"/><bf gi="126" ue="174" us="174"/><bf gi="74" ue="175" us="175"/><bf gi="128" ue="176" us="176"/><bf gi="151" ue="177" us="177"/><bf gi="1202" ue="179" us="178"/><bf gi="69" ue="180" us="180"/><bf gi="224" ue="181" us="181"/><bf gi="118" ue="182" us="182"/><bf gi="107" ue="183" us="183"/><bf gi="79" ue="184" us="184"/><bf gi="1204" ue="185" us="185"/><bf gi="67" ue="186" us="186"/><bf gi="98" ue="187" us="187"/><bf gi="1205" ue="190" us="188"/><bf gi="168" ue="191" us="191"/><bf gi="172" ue="197" us="192"/><bf gi="4" ue="198" us="198"/><bf gi="7" ue="199" us="199"/><bf gi="178" ue="207" us="200"/><bf gi="226" ue="208" us="208"/><bf gi="186" ue="214" us="209"/><bf gi="517" ue="215" us="215"/><bf gi="20" ue="216" us="216"/><bf gi="192" ue="220" us="217"/><bf gi="2203" ue="221" us="221"/><bf gi="233" ue="222" us="222"/><bf gi="58" ue="223" us="223"/><bf gi="197" ue="229" us="224"/><bf gi="34" ue="230" us="230"/><bf gi="37" ue="231" us="231"/><bf gi="203" ue="239" us="232"/><bf gi="244" ue="240" us="240"/><bf gi="211" ue="246" us="241"/><bf gi="145" ue="247" us="247"/><bf gi="52" ue="248" us="248"/><bf gi="217" ue="252" us="249"/><bf gi="2538" ue="253" us="253"/><bf gi="285" ue="254" us="254"/><bf gi="221" ue="255" us="255"/><bf gi="1889" ue="256" us="256"/><bf gi="2229" ue="257" us="257"/><bf gi="1890" ue="258" us="258"/><bf gi="2230" ue="259" us="259"/><bf gi="225" ue="260" us="260"/><bf gi="237" ue="261" us="261"/><bf gi="1947" ue="262" us="262"/><bf gi="2263" ue="263" us="263"/><bf gi="1948" ue="264" us="264"/><bf gi="2264" ue="265" us="265"/><bf gi="1950" ue="266" us="266"/><bf gi="2266" ue="267" us="267"/><bf gi="1949" ue="268" us="268"/><bf gi="2265" ue="269" us="269"/><bf gi="1955" ue="270" us="270"/><bf gi="242" ue="271" us="271"/><bf gi="1962" ue="272" us="272"/><bf gi="243" ue="273" us="273"/><bf gi="1965" ue="274" us="274"/><bf gi="2279" ue="275" us="275"/><bf gi="1966" ue="276" us="276"/><bf gi="2280" ue="277" us="277"/><bf gi="1967" ue="278" us="278"/><bf gi="2281" ue="279" us="279"/><bf gi="227" ue="280" us="280"/><bf gi="245" ue="281" us="281"/><bf gi="1964" ue="282" us="282"/><bf gi="2278" ue="283" us="283"/><bf gi="2000" ue="284" us="284"/><bf gi="2322" ue="285" us="285"/><bf gi="2001" ue="286" us="286"/><bf gi="2323" ue="287" us="287"/><bf gi="2002" ue="288" us="288"/><bf gi="2324" ue="289" us="289"/><bf gi="2003" ue="290" us="290"/><bf gi="2325" ue="291" us="291"/><bf gi="2007" ue="292" us="292"/><bf gi="276" ue="293" uLine truncated
Binary file not shown.
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Lato-MediumItalic</font-name><full-name>Lato Medium Italic</full-name><family-name>Lato</family-name><embed/><cap-height>717</cap-height><x-height>507</x-height><ascender>805</ascender><descender>-195</descender><bbox><left>-504</left><bottom>-269</bottom><right>1291</right><top>1080</top></bbox><flags>97</flags><stemv>0</stemv><italicangle>-7</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="1" ue="0" us="0"/><bf gi="169" ue="13" us="13"/><bf gi="2" ue="32" us="32"/><bf gi="81" ue="33" us="33"/><bf gi="120" ue="34" us="34"/><bf gi="132" ue="35" us="35"/><bf gi="128" ue="36" us="36"/><bf gi="164" ue="37" us="37"/><bf gi="121" ue="38" us="38"/><bf gi="119" ue="39" us="39"/><bf gi="106" ue="41" us="40"/><bf gi="112" ue="42" us="42"/><bf gi="142" ue="43" us="43"/><bf gi="83" ue="44" us="44"/><bf gi="100" ue="45" us="45"/><bf gi="85" ue="46" us="46"/><bf gi="97" ue="47" us="47"/><bf gi="133" ue="53" us="48"/><bf gi="162" ue="54" us="54"/><bf gi="139" ue="55" us="55"/><bf gi="163" ue="56" us="56"/><bf gi="140" ue="57" us="57"/><bf gi="170" ue="58" us="58"/><bf gi="84" ue="59" us="59"/><bf gi="147" ue="60" us="60"/><bf gi="144" ue="61" us="61"/><bf gi="148" ue="62" us="62"/><bf gi="82" ue="63" us="63"/><bf gi="122" ue="64" us="64"/><bf gi="3" ue="65" us="65"/><bf gi="5" ue="67" us="66"/><bf gi="8" ue="79" us="68"/><bf gi="22" ue="90" us="80"/><bf gi="108" ue="91" us="91"/><bf gi="99" ue="92" us="92"/><bf gi="109" ue="93" us="93"/><bf gi="117" ue="94" us="94"/><bf gi="103" ue="95" us="95"/><bf gi="68" ue="96" us="96"/><bf gi="33" ue="97" us="97"/><bf gi="35" ue="99" us="98"/><bf gi="38" ue="102" us="100"/><bf gi="43" ue="105" us="103"/><bf gi="47" ue="107" us="106"/><bf gi="161" ue="108" us="108"/><bf gi="49" ue="111" us="109"/><bf gi="54" ue="115" us="112"/><bf gi="59" ue="122" us="116"/><bf gi="110" ue="123" us="123"/><bf gi="98" ue="124" us="124"/><bf gi="111" ue="125" us="125"/><bf gi="118" ue="126" us="126"/><bf gi="2" ue="160" us="160"/><bf gi="165" ue="161" us="161"/><bf gi="129" ue="163" us="162"/><bf gi="455" ue="164" us="164"/><bf gi="131" ue="165" us="165"/><bf gi="452" ue="166" us="166"/><bf gi="115" ue="167" us="167"/><bf gi="171" ue="168" us="168"/><bf gi="123" ue="169" us="169"/><bf gi="66" ue="170" us="170"/><bf gi="95" ue="171" us="171"/><bf gi="152" ue="172" us="172"/><bf gi="100" ue="173" us="173"/><bf gi="124" ue="174" us="174"/><bf gi="73" ue="175" us="175"/><bf gi="126" ue="176" us="176"/><bf gi="149" ue="177" us="177"/><bf gi="1202" ue="179" us="178"/><bf gi="69" ue="180" us="180"/><bf gi="224" ue="181" us="181"/><bf gi="116" ue="182" us="182"/><bf gi="105" ue="183" us="183"/><bf gi="78" ue="184" us="184"/><bf gi="1204" ue="185" us="185"/><bf gi="67" ue="186" us="186"/><bf gi="96" ue="187" us="187"/><bf gi="1205" ue="190" us="188"/><bf gi="166" ue="191" us="191"/><bf gi="172" ue="197" us="192"/><bf gi="4" ue="198" us="198"/><bf gi="7" ue="199" us="199"/><bf gi="178" ue="207" us="200"/><bf gi="226" ue="208" us="208"/><bf gi="186" ue="214" us="209"/><bf gi="517" ue="215" us="215"/><bf gi="20" ue="216" us="216"/><bf gi="192" ue="220" us="217"/><bf gi="1973" ue="221" us="221"/><bf gi="233" ue="222" us="222"/><bf gi="58" ue="223" us="223"/><bf gi="197" ue="229" us="224"/><bf gi="34" ue="230" us="230"/><bf gi="37" ue="231" us="231"/><bf gi="203" ue="239" us="232"/><bf gi="244" ue="240" us="240"/><bf gi="211" ue="246" us="241"/><bf gi="143" ue="247" us="247"/><bf gi="52" ue="248" us="248"/><bf gi="217" ue="252" us="249"/><bf gi="2312" ue="253" us="253"/><bf gi="285" ue="254" us="254"/><bf gi="221" ue="255" us="255"/><bf gi="1659" ue="256" us="256"/><bf gi="1999" ue="257" us="257"/><bf gi="1660" ue="258" us="258"/><bf gi="2000" ue="259" us="259"/><bf gi="225" ue="260" us="260"/><bf gi="237" ue="261" us="261"/><bf gi="1717" ue="262" us="262"/><bf gi="2033" ue="263" us="263"/><bf gi="1718" ue="264" us="264"/><bf gi="2034" ue="265" us="265"/><bf gi="1720" ue="266" us="266"/><bf gi="2036" ue="267" us="267"/><bf gi="1719" ue="268" us="268"/><bf gi="2035" ue="269" us="269"/><bf gi="1725" ue="270" us="270"/><bf gi="242" ue="271" us="271"/><bf gi="1732" ue="272" us="272"/><bf gi="243" ue="273" us="273"/><bf gi="1735" ue="274" us="274"/><bf gi="2049" ue="275" us="275"/><bf gi="1736" ue="276" us="276"/><bf gi="2050" ue="277" us="277"/><bf gi="1737" ue="278" us="278"/><bf gi="2051" ue="279" us="279"/><bf gi="227" ue="280" us="280"/><bf gi="245" ue="281" us="281"/><bf gi="1734" ue="282" us="282"/><bf gi="2048" ue="283" us="283"/><bf gi="1770" ue="284" us="284"/><bf gi="2092" ue="285" us="285"/><bf gi="1771" ue="286" us="286"/><bf gi="2093" ue="287" us="287"/><bf gi="1772" ue="288" us="288"/><bf gi="2094" ue="289" us="289"/><bf gi="1773" ue="290" us="290"/><bf gi="2095" ue="291" us="291"/><bf gi="1777" ue="292" us="292"/><bf gi="2Line truncated
Binary file not shown.
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Lato-Regular</font-name><full-name>Lato Regular</full-name><family-name>Lato</family-name><embed/><cap-height>716</cap-height><x-height>506</x-height><ascender>805</ascender><descender>-195</descender><bbox><left>-546</left><bottom>-268</bottom><right>1342</right><top>1078</top></bbox><flags>33</flags><stemv>0</stemv><italicangle>0</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="1" ue="0" us="0"/><bf gi="171" ue="13" us="13"/><bf gi="2" ue="32" us="32"/><bf gi="82" ue="33" us="33"/><bf gi="122" ue="34" us="34"/><bf gi="134" ue="35" us="35"/><bf gi="130" ue="36" us="36"/><bf gi="166" ue="37" us="37"/><bf gi="123" ue="38" us="38"/><bf gi="121" ue="39" us="39"/><bf gi="108" ue="41" us="40"/><bf gi="114" ue="42" us="42"/><bf gi="144" ue="43" us="43"/><bf gi="84" ue="44" us="44"/><bf gi="102" ue="45" us="45"/><bf gi="87" ue="46" us="46"/><bf gi="99" ue="47" us="47"/><bf gi="135" ue="53" us="48"/><bf gi="164" ue="54" us="54"/><bf gi="141" ue="55" us="55"/><bf gi="165" ue="56" us="56"/><bf gi="142" ue="57" us="57"/><bf gi="86" ue="58" us="58"/><bf gi="85" ue="59" us="59"/><bf gi="149" ue="60" us="60"/><bf gi="146" ue="61" us="61"/><bf gi="150" ue="62" us="62"/><bf gi="83" ue="63" us="63"/><bf gi="124" ue="64" us="64"/><bf gi="3" ue="65" us="65"/><bf gi="5" ue="67" us="66"/><bf gi="8" ue="79" us="68"/><bf gi="22" ue="90" us="80"/><bf gi="110" ue="91" us="91"/><bf gi="101" ue="92" us="92"/><bf gi="111" ue="93" us="93"/><bf gi="119" ue="94" us="94"/><bf gi="105" ue="95" us="95"/><bf gi="68" ue="96" us="96"/><bf gi="33" ue="97" us="97"/><bf gi="35" ue="99" us="98"/><bf gi="38" ue="102" us="100"/><bf gi="43" ue="105" us="103"/><bf gi="47" ue="107" us="106"/><bf gi="163" ue="108" us="108"/><bf gi="49" ue="111" us="109"/><bf gi="54" ue="115" us="112"/><bf gi="59" ue="122" us="116"/><bf gi="112" ue="123" us="123"/><bf gi="100" ue="124" us="124"/><bf gi="113" ue="125" us="125"/><bf gi="120" ue="126" us="126"/><bf gi="2" ue="160" us="160"/><bf gi="167" ue="161" us="161"/><bf gi="131" ue="163" us="162"/><bf gi="455" ue="164" us="164"/><bf gi="133" ue="165" us="165"/><bf gi="452" ue="166" us="166"/><bf gi="117" ue="167" us="167"/><bf gi="73" ue="168" us="168"/><bf gi="125" ue="169" us="169"/><bf gi="66" ue="170" us="170"/><bf gi="97" ue="171" us="171"/><bf gi="154" ue="172" us="172"/><bf gi="102" ue="173" us="173"/><bf gi="126" ue="174" us="174"/><bf gi="74" ue="175" us="175"/><bf gi="128" ue="176" us="176"/><bf gi="151" ue="177" us="177"/><bf gi="1202" ue="179" us="178"/><bf gi="69" ue="180" us="180"/><bf gi="224" ue="181" us="181"/><bf gi="118" ue="182" us="182"/><bf gi="107" ue="183" us="183"/><bf gi="79" ue="184" us="184"/><bf gi="1204" ue="185" us="185"/><bf gi="67" ue="186" us="186"/><bf gi="98" ue="187" us="187"/><bf gi="1205" ue="190" us="188"/><bf gi="168" ue="191" us="191"/><bf gi="172" ue="197" us="192"/><bf gi="4" ue="198" us="198"/><bf gi="7" ue="199" us="199"/><bf gi="178" ue="207" us="200"/><bf gi="226" ue="208" us="208"/><bf gi="186" ue="214" us="209"/><bf gi="517" ue="215" us="215"/><bf gi="20" ue="216" us="216"/><bf gi="192" ue="220" us="217"/><bf gi="2203" ue="221" us="221"/><bf gi="233" ue="222" us="222"/><bf gi="58" ue="223" us="223"/><bf gi="197" ue="229" us="224"/><bf gi="34" ue="230" us="230"/><bf gi="37" ue="231" us="231"/><bf gi="203" ue="239" us="232"/><bf gi="244" ue="240" us="240"/><bf gi="211" ue="246" us="241"/><bf gi="145" ue="247" us="247"/><bf gi="52" ue="248" us="248"/><bf gi="217" ue="252" us="249"/><bf gi="2538" ue="253" us="253"/><bf gi="285" ue="254" us="254"/><bf gi="221" ue="255" us="255"/><bf gi="1889" ue="256" us="256"/><bf gi="2229" ue="257" us="257"/><bf gi="1890" ue="258" us="258"/><bf gi="2230" ue="259" us="259"/><bf gi="225" ue="260" us="260"/><bf gi="237" ue="261" us="261"/><bf gi="1947" ue="262" us="262"/><bf gi="2263" ue="263" us="263"/><bf gi="1948" ue="264" us="264"/><bf gi="2264" ue="265" us="265"/><bf gi="1950" ue="266" us="266"/><bf gi="2266" ue="267" us="267"/><bf gi="1949" ue="268" us="268"/><bf gi="2265" ue="269" us="269"/><bf gi="1955" ue="270" us="270"/><bf gi="242" ue="271" us="271"/><bf gi="1962" ue="272" us="272"/><bf gi="243" ue="273" us="273"/><bf gi="1965" ue="274" us="274"/><bf gi="2279" ue="275" us="275"/><bf gi="1966" ue="276" us="276"/><bf gi="2280" ue="277" us="277"/><bf gi="1967" ue="278" us="278"/><bf gi="2281" ue="279" us="279"/><bf gi="227" ue="280" us="280"/><bf gi="245" ue="281" us="281"/><bf gi="1964" ue="282" us="282"/><bf gi="2278" ue="283" us="283"/><bf gi="2000" ue="284" us="284"/><bf gi="2322" ue="285" us="285"/><bf gi="2001" ue="286" us="286"/><bf gi="2323" ue="287" us="287"/><bf gi="2002" ue="288" us="288"/><bf gi="2324" ue="289" us="289"/><bf gi="2003" ue="290" us="290"/><bf gi="2325" ue="291" us="291"/><bf gi="2007" ue="292" us="292"/><bf gi="276" ue="293"Line truncated
Binary file not shown.
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Lato-Semibold</font-name><full-name>Lato Semibold</full-name><family-name>Lato</family-name><embed/><cap-height>720</cap-height><x-height>510</x-height><ascender>805</ascender><descender>-195</descender><bbox><left>-576</left><bottom>-277</bottom><right>1343</right><top>1090</top></bbox><flags>33</flags><stemv>0</stemv><italicangle>0</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="1" ue="0" us="0"/><bf gi="171" ue="13" us="13"/><bf gi="2" ue="32" us="32"/><bf gi="82" ue="33" us="33"/><bf gi="122" ue="34" us="34"/><bf gi="134" ue="35" us="35"/><bf gi="130" ue="36" us="36"/><bf gi="166" ue="37" us="37"/><bf gi="123" ue="38" us="38"/><bf gi="121" ue="39" us="39"/><bf gi="108" ue="41" us="40"/><bf gi="114" ue="42" us="42"/><bf gi="144" ue="43" us="43"/><bf gi="84" ue="44" us="44"/><bf gi="102" ue="45" us="45"/><bf gi="87" ue="46" us="46"/><bf gi="99" ue="47" us="47"/><bf gi="135" ue="53" us="48"/><bf gi="164" ue="54" us="54"/><bf gi="141" ue="55" us="55"/><bf gi="165" ue="56" us="56"/><bf gi="142" ue="57" us="57"/><bf gi="86" ue="58" us="58"/><bf gi="85" ue="59" us="59"/><bf gi="149" ue="60" us="60"/><bf gi="146" ue="61" us="61"/><bf gi="150" ue="62" us="62"/><bf gi="83" ue="63" us="63"/><bf gi="124" ue="64" us="64"/><bf gi="3" ue="65" us="65"/><bf gi="5" ue="67" us="66"/><bf gi="8" ue="79" us="68"/><bf gi="22" ue="90" us="80"/><bf gi="110" ue="91" us="91"/><bf gi="101" ue="92" us="92"/><bf gi="111" ue="93" us="93"/><bf gi="119" ue="94" us="94"/><bf gi="105" ue="95" us="95"/><bf gi="68" ue="96" us="96"/><bf gi="33" ue="97" us="97"/><bf gi="35" ue="99" us="98"/><bf gi="38" ue="102" us="100"/><bf gi="43" ue="105" us="103"/><bf gi="47" ue="107" us="106"/><bf gi="163" ue="108" us="108"/><bf gi="49" ue="111" us="109"/><bf gi="54" ue="115" us="112"/><bf gi="59" ue="122" us="116"/><bf gi="112" ue="123" us="123"/><bf gi="100" ue="124" us="124"/><bf gi="113" ue="125" us="125"/><bf gi="120" ue="126" us="126"/><bf gi="2" ue="160" us="160"/><bf gi="167" ue="161" us="161"/><bf gi="131" ue="163" us="162"/><bf gi="455" ue="164" us="164"/><bf gi="133" ue="165" us="165"/><bf gi="452" ue="166" us="166"/><bf gi="117" ue="167" us="167"/><bf gi="73" ue="168" us="168"/><bf gi="125" ue="169" us="169"/><bf gi="66" ue="170" us="170"/><bf gi="97" ue="171" us="171"/><bf gi="154" ue="172" us="172"/><bf gi="102" ue="173" us="173"/><bf gi="126" ue="174" us="174"/><bf gi="74" ue="175" us="175"/><bf gi="128" ue="176" us="176"/><bf gi="151" ue="177" us="177"/><bf gi="1202" ue="179" us="178"/><bf gi="69" ue="180" us="180"/><bf gi="224" ue="181" us="181"/><bf gi="118" ue="182" us="182"/><bf gi="107" ue="183" us="183"/><bf gi="79" ue="184" us="184"/><bf gi="1204" ue="185" us="185"/><bf gi="67" ue="186" us="186"/><bf gi="98" ue="187" us="187"/><bf gi="1205" ue="190" us="188"/><bf gi="168" ue="191" us="191"/><bf gi="172" ue="197" us="192"/><bf gi="4" ue="198" us="198"/><bf gi="7" ue="199" us="199"/><bf gi="178" ue="207" us="200"/><bf gi="226" ue="208" us="208"/><bf gi="186" ue="214" us="209"/><bf gi="517" ue="215" us="215"/><bf gi="20" ue="216" us="216"/><bf gi="192" ue="220" us="217"/><bf gi="2203" ue="221" us="221"/><bf gi="233" ue="222" us="222"/><bf gi="58" ue="223" us="223"/><bf gi="197" ue="229" us="224"/><bf gi="34" ue="230" us="230"/><bf gi="37" ue="231" us="231"/><bf gi="203" ue="239" us="232"/><bf gi="244" ue="240" us="240"/><bf gi="211" ue="246" us="241"/><bf gi="145" ue="247" us="247"/><bf gi="52" ue="248" us="248"/><bf gi="217" ue="252" us="249"/><bf gi="2538" ue="253" us="253"/><bf gi="285" ue="254" us="254"/><bf gi="221" ue="255" us="255"/><bf gi="1889" ue="256" us="256"/><bf gi="2229" ue="257" us="257"/><bf gi="1890" ue="258" us="258"/><bf gi="2230" ue="259" us="259"/><bf gi="225" ue="260" us="260"/><bf gi="237" ue="261" us="261"/><bf gi="1947" ue="262" us="262"/><bf gi="2263" ue="263" us="263"/><bf gi="1948" ue="264" us="264"/><bf gi="2264" ue="265" us="265"/><bf gi="1950" ue="266" us="266"/><bf gi="2266" ue="267" us="267"/><bf gi="1949" ue="268" us="268"/><bf gi="2265" ue="269" us="269"/><bf gi="1955" ue="270" us="270"/><bf gi="242" ue="271" us="271"/><bf gi="1962" ue="272" us="272"/><bf gi="243" ue="273" us="273"/><bf gi="1965" ue="274" us="274"/><bf gi="2279" ue="275" us="275"/><bf gi="1966" ue="276" us="276"/><bf gi="2280" ue="277" us="277"/><bf gi="1967" ue="278" us="278"/><bf gi="2281" ue="279" us="279"/><bf gi="227" ue="280" us="280"/><bf gi="245" ue="281" us="281"/><bf gi="1964" ue="282" us="282"/><bf gi="2278" ue="283" us="283"/><bf gi="2000" ue="284" us="284"/><bf gi="2322" ue="285" us="285"/><bf gi="2001" ue="286" us="286"/><bf gi="2323" ue="287" us="287"/><bf gi="2002" ue="288" us="288"/><bf gi="2324" ue="289" us="289"/><bf gi="2003" ue="290" us="290"/><bf gi="2325" ue="291" us="291"/><bf gi="2007" ue="292" us="292"/><bf gi="276" ue="29Line truncated
Binary file not shown.
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><font-metrics metrics-version="2" type="TYPE0"><font-name>Lato-SemiboldItalic</font-name><full-name>Lato Semibold Italic</full-name><family-name>Lato</family-name><embed/><cap-height>720</cap-height><x-height>510</x-height><ascender>805</ascender><descender>-195</descender><bbox><left>-511</left><bottom>-275</bottom><right>1291</right><top>1088</top></bbox><flags>97</flags><stemv>0</stemv><italicangle>-7</italicangle><subtype>TYPE0</subtype><multibyte-extras><cid-type>CIDFontType2</cid-type><default-width>0</default-width><bfranges><bf gi="1" ue="0" us="0"/><bf gi="169" ue="13" us="13"/><bf gi="2" ue="32" us="32"/><bf gi="81" ue="33" us="33"/><bf gi="120" ue="34" us="34"/><bf gi="132" ue="35" us="35"/><bf gi="128" ue="36" us="36"/><bf gi="164" ue="37" us="37"/><bf gi="121" ue="38" us="38"/><bf gi="119" ue="39" us="39"/><bf gi="106" ue="41" us="40"/><bf gi="112" ue="42" us="42"/><bf gi="142" ue="43" us="43"/><bf gi="83" ue="44" us="44"/><bf gi="100" ue="45" us="45"/><bf gi="85" ue="46" us="46"/><bf gi="97" ue="47" us="47"/><bf gi="133" ue="53" us="48"/><bf gi="162" ue="54" us="54"/><bf gi="139" ue="55" us="55"/><bf gi="163" ue="56" us="56"/><bf gi="140" ue="57" us="57"/><bf gi="170" ue="58" us="58"/><bf gi="84" ue="59" us="59"/><bf gi="147" ue="60" us="60"/><bf gi="144" ue="61" us="61"/><bf gi="148" ue="62" us="62"/><bf gi="82" ue="63" us="63"/><bf gi="122" ue="64" us="64"/><bf gi="3" ue="65" us="65"/><bf gi="5" ue="67" us="66"/><bf gi="8" ue="79" us="68"/><bf gi="22" ue="90" us="80"/><bf gi="108" ue="91" us="91"/><bf gi="99" ue="92" us="92"/><bf gi="109" ue="93" us="93"/><bf gi="117" ue="94" us="94"/><bf gi="103" ue="95" us="95"/><bf gi="68" ue="96" us="96"/><bf gi="33" ue="97" us="97"/><bf gi="35" ue="99" us="98"/><bf gi="38" ue="102" us="100"/><bf gi="43" ue="105" us="103"/><bf gi="47" ue="107" us="106"/><bf gi="161" ue="108" us="108"/><bf gi="49" ue="111" us="109"/><bf gi="54" ue="115" us="112"/><bf gi="59" ue="122" us="116"/><bf gi="110" ue="123" us="123"/><bf gi="98" ue="124" us="124"/><bf gi="111" ue="125" us="125"/><bf gi="118" ue="126" us="126"/><bf gi="2" ue="160" us="160"/><bf gi="165" ue="161" us="161"/><bf gi="129" ue="163" us="162"/><bf gi="455" ue="164" us="164"/><bf gi="131" ue="165" us="165"/><bf gi="452" ue="166" us="166"/><bf gi="115" ue="167" us="167"/><bf gi="171" ue="168" us="168"/><bf gi="123" ue="169" us="169"/><bf gi="66" ue="170" us="170"/><bf gi="95" ue="171" us="171"/><bf gi="152" ue="172" us="172"/><bf gi="100" ue="173" us="173"/><bf gi="124" ue="174" us="174"/><bf gi="73" ue="175" us="175"/><bf gi="126" ue="176" us="176"/><bf gi="149" ue="177" us="177"/><bf gi="1202" ue="179" us="178"/><bf gi="69" ue="180" us="180"/><bf gi="224" ue="181" us="181"/><bf gi="116" ue="182" us="182"/><bf gi="105" ue="183" us="183"/><bf gi="78" ue="184" us="184"/><bf gi="1204" ue="185" us="185"/><bf gi="67" ue="186" us="186"/><bf gi="96" ue="187" us="187"/><bf gi="1205" ue="190" us="188"/><bf gi="166" ue="191" us="191"/><bf gi="172" ue="197" us="192"/><bf gi="4" ue="198" us="198"/><bf gi="7" ue="199" us="199"/><bf gi="178" ue="207" us="200"/><bf gi="226" ue="208" us="208"/><bf gi="186" ue="214" us="209"/><bf gi="517" ue="215" us="215"/><bf gi="20" ue="216" us="216"/><bf gi="192" ue="220" us="217"/><bf gi="1973" ue="221" us="221"/><bf gi="233" ue="222" us="222"/><bf gi="58" ue="223" us="223"/><bf gi="197" ue="229" us="224"/><bf gi="34" ue="230" us="230"/><bf gi="37" ue="231" us="231"/><bf gi="203" ue="239" us="232"/><bf gi="244" ue="240" us="240"/><bf gi="211" ue="246" us="241"/><bf gi="143" ue="247" us="247"/><bf gi="52" ue="248" us="248"/><bf gi="217" ue="252" us="249"/><bf gi="2312" ue="253" us="253"/><bf gi="285" ue="254" us="254"/><bf gi="221" ue="255" us="255"/><bf gi="1659" ue="256" us="256"/><bf gi="1999" ue="257" us="257"/><bf gi="1660" ue="258" us="258"/><bf gi="2000" ue="259" us="259"/><bf gi="225" ue="260" us="260"/><bf gi="237" ue="261" us="261"/><bf gi="1717" ue="262" us="262"/><bf gi="2033" ue="263" us="263"/><bf gi="1718" ue="264" us="264"/><bf gi="2034" ue="265" us="265"/><bf gi="1720" ue="266" us="266"/><bf gi="2036" ue="267" us="267"/><bf gi="1719" ue="268" us="268"/><bf gi="2035" ue="269" us="269"/><bf gi="1725" ue="270" us="270"/><bf gi="242" ue="271" us="271"/><bf gi="1732" ue="272" us="272"/><bf gi="243" ue="273" us="273"/><bf gi="1735" ue="274" us="274"/><bf gi="2049" ue="275" us="275"/><bf gi="1736" ue="276" us="276"/><bf gi="2050" ue="277" us="277"/><bf gi="1737" ue="278" us="278"/><bf gi="2051" ue="279" us="279"/><bf gi="227" ue="280" us="280"/><bf gi="245" ue="281" us="281"/><bf gi="1734" ue="282" us="282"/><bf gi="2048" ue="283" us="283"/><bf gi="1770" ue="284" us="284"/><bf gi="2092" ue="285" us="285"/><bf gi="1771" ue="286" us="286"/><bf gi="2093" ue="287" us="287"/><bf gi="1772" ue="288" us="288"/><bf gi="2094" ue="289" us="289"/><bf gi="1773" ue="290" us="290"/><bf gi="2095" ue="291" us="291"/><bf gi="1777" ue="292" us="292"/><bf gLine truncated
Loaded 100 of 1330 files, more files were not shown because too many files have changed in this diff. Show more