(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o').appendTo('body'); $window.on('error', function (oEvent) { if (oEvent && oEvent.originalEvent && oEvent.originalEvent.message && -1 === Utils.inArray(oEvent.originalEvent.message, [ 'Script error.', 'Uncaught Error: Error calling method on NPObject.' ])) { Remote().jsError( Utils.emptyFunction, oEvent.originalEvent.message, oEvent.originalEvent.filename, oEvent.originalEvent.lineno, window.location && window.location.toString ? window.location.toString() : '', $html.attr('class'), Utils.microtime() - Globals.now ); } }); $doc.on('keydown', function (oEvent) { if (oEvent && oEvent.ctrlKey) { $html.addClass('rl-ctrl-key-pressed'); } }).on('keyup', function (oEvent) { if (oEvent && !oEvent.ctrlKey) { $html.removeClass('rl-ctrl-key-pressed'); } }); } _.extend(AbstractApp.prototype, KnoinAbstractBoot.prototype); AbstractApp.prototype.oSettings = null; AbstractApp.prototype.oPlugins = null; AbstractApp.prototype.oLocal = null; AbstractApp.prototype.oLink = null; AbstractApp.prototype.oSubs = {}; /** * @param {string} sLink * @return {boolean} */ AbstractApp.prototype.download = function (sLink) { var oE = null, oLink = null, sUserAgent = window.navigator.userAgent.toLowerCase() ; if (sUserAgent && (sUserAgent.indexOf('chrome') > -1 || sUserAgent.indexOf('chrome') > -1)) { oLink = window.document.createElement('a'); oLink['href'] = sLink; if (window.document['createEvent']) { oE = window.document['createEvent']('MouseEvents'); if (oE && oE['initEvent'] && oLink['dispatchEvent']) { oE['initEvent']('click', true, true); oLink['dispatchEvent'](oE); return true; } } } if (Globals.bMobileDevice) { window.open(sLink, '_self'); window.focus(); } else { this.iframe.attr('src', sLink); // window.document.location.href = sLink; } return true; }; /** * @param {string} sName * @return {?} */ AbstractApp.prototype.settingsGet = function (sName) { if (null === this.oSettings) { this.oSettings = Utils.isNormal(AppData) ? AppData : {}; } return Utils.isUnd(this.oSettings[sName]) ? null : this.oSettings[sName]; }; /** * @param {string} sName * @param {?} mValue */ AbstractApp.prototype.settingsSet = function (sName, mValue) { if (null === this.oSettings) { this.oSettings = Utils.isNormal(AppData) ? AppData : {}; } this.oSettings[sName] = mValue; }; AbstractApp.prototype.setTitle = function (sTitle) { sTitle = ((Utils.isNormal(sTitle) && 0 < sTitle.length) ? sTitle + ' - ' : '') + this.settingsGet('Title') || ''; window.document.title = '_'; window.document.title = sTitle; }; /** * @param {boolean=} bLogout = false * @param {boolean=} bClose = false */ AbstractApp.prototype.loginAndLogoutReload = function (bLogout, bClose) { var sCustomLogoutLink = Utils.pString(this.settingsGet('CustomLogoutLink')), bInIframe = !!this.settingsGet('InIframe') ; bLogout = Utils.isUnd(bLogout) ? false : !!bLogout; bClose = Utils.isUnd(bClose) ? false : !!bClose; if (bLogout && bClose && window.close) { window.close(); } if (bLogout && '' !== sCustomLogoutLink && window.location.href !== sCustomLogoutLink) { _.delay(function () { if (bInIframe && window.parent) { window.parent.location.href = sCustomLogoutLink; } else { window.location.href = sCustomLogoutLink; } }, 100); } else { kn.routeOff(); kn.setHash(LinkBuilder.root(), true); kn.routeOff(); _.delay(function () { if (bInIframe && window.parent) { window.parent.location.reload(); } else { window.location.reload(); } }, 100); } }; AbstractApp.prototype.historyBack = function () { window.history.back(); }; /** * @param {string} sQuery * @param {Function} fCallback */ AbstractApp.prototype.getAutocomplete = function (sQuery, fCallback) { fCallback([], sQuery); }; /** * @param {string} sName * @param {Function} fFunc * @param {Object=} oContext * @return {AbstractApp} */ AbstractApp.prototype.sub = function (sName, fFunc, oContext) { if (Utils.isUnd(this.oSubs[sName])) { this.oSubs[sName] = []; } this.oSubs[sName].push([fFunc, oContext]); return this; }; /** * @param {string} sName * @param {Array=} aArgs * @return {AbstractApp} */ AbstractApp.prototype.pub = function (sName, aArgs) { Plugins.runHook('rl-pub', [sName, aArgs]); if (!Utils.isUnd(this.oSubs[sName])) { _.each(this.oSubs[sName], function (aItem) { if (aItem[0]) { aItem[0].apply(aItem[1] || null, aArgs || []); } }); } return this; }; /** * @param {string} sName * @return {boolean} */ AbstractApp.prototype.capa = function (sName) { var mCapa = this.settingsGet('Capa'); return Utils.isArray(mCapa) && Utils.isNormal(sName) && -1 < Utils.inArray(sName, mCapa); }; AbstractApp.prototype.bootstart = function () { var self = this, ssm = require('../External/ssm.js') ; Utils.initOnStartOrLangChange(function () { Utils.initNotificationLanguage(); }, null); _.delay(function () { Utils.windowResize(); }, 1000); ssm.addState({ 'id': 'mobile', 'maxWidth': 767, 'onEnter': function() { $html.addClass('ssm-state-mobile'); self.pub('ssm.mobile-enter'); }, 'onLeave': function() { $html.removeClass('ssm-state-mobile'); self.pub('ssm.mobile-leave'); } }); ssm.addState({ 'id': 'tablet', 'minWidth': 768, 'maxWidth': 999, 'onEnter': function() { $html.addClass('ssm-state-tablet'); }, 'onLeave': function() { $html.removeClass('ssm-state-tablet'); } }); ssm.addState({ 'id': 'desktop', 'minWidth': 1000, 'maxWidth': 1400, 'onEnter': function() { $html.addClass('ssm-state-desktop'); }, 'onLeave': function() { $html.removeClass('ssm-state-desktop'); } }); ssm.addState({ 'id': 'desktop-large', 'minWidth': 1400, 'onEnter': function() { $html.addClass('ssm-state-desktop-large'); }, 'onLeave': function() { $html.removeClass('ssm-state-desktop-large'); } }); this.sub('ssm.mobile-enter', function () { RL.data().leftPanelDisabled(true); // TODO cjs }); this.sub('ssm.mobile-leave', function () { RL.data().leftPanelDisabled(false); // TODO cjs }); RL.data().leftPanelDisabled.subscribe(function (bValue) { // TODO cjs $html.toggleClass('rl-left-panel-disabled', bValue); }); ssm.ready(); }; module.exports = AbstractApp; }(module)); },{"../Common/Globals.js":6,"../Common/LinkBuilder.js":7,"../Common/Plugins.js":8,"../Common/Utils.js":9,"../External/$doc.js":11,"../External/$html.js":12,"../External/$window.js":13,"../External/AppData.js":14,"../External/jquery.js":19,"../External/ko.js":21,"../External/ssm.js":23,"../External/underscore.js":24,"../External/window.js":25,"../Knoin/Knoin.js":26,"../Knoin/KnoinAbstractBoot.js":27,"../Remote.js":33}],3:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ (function (module) { 'use strict'; var window = require('../External/window.js'), $ = require('../External/jquery.js'), _ = require('../External/underscore.js'), moment = require('../External/moment.js'), Enums = require('../Common/Enums.js'), Globals = require('../Common/Globals.js'), Consts = require('../Common/Consts.js'), Plugins = require('../Common/Plugins.js'), Utils = require('../Common/Utils.js'), LinkBuilder = require('../Common/LinkBuilder.js'), kn = require('../Knoin/Knoin.js'), Data = require('../Storages/WebMailDataStorage.js'), Cache = require('../Storages/WebMailCacheStorage.js'), Remote = require('../Storages/WebMailAjaxRemoteStorage.js'), PopupsFolderSystemViewModel = require('../ViewModels/Popups/PopupsAskViewModel.js'), PopupsAskViewModel = require('../ViewModels/Popups/PopupsAskViewModel.js'), AbstractApp = require('./AbstractApp.js') ; /** * @constructor * @extends AbstractApp */ function RainLoopApp() { AbstractApp.call(this); this.oData = null; this.oRemote = null; this.oCache = null; this.oMoveCache = {}; this.quotaDebounce = _.debounce(this.quota, 1000 * 30); this.moveOrDeleteResponseHelper = _.bind(this.moveOrDeleteResponseHelper, this); this.messagesMoveTrigger = _.debounce(this.messagesMoveTrigger, 500); window.setInterval(function () { RL.pub('interval.30s'); }, 30000); window.setInterval(function () { RL.pub('interval.1m'); }, 60000); window.setInterval(function () { RL.pub('interval.2m'); }, 60000 * 2); window.setInterval(function () { RL.pub('interval.3m'); }, 60000 * 3); window.setInterval(function () { RL.pub('interval.5m'); }, 60000 * 5); window.setInterval(function () { RL.pub('interval.10m'); }, 60000 * 10); window.setTimeout(function () { window.setInterval(function () { RL.pub('interval.10m-after5m'); }, 60000 * 10); }, 60000 * 5); $.wakeUp(function () { Remote.jsVersion(function (sResult, oData) { if (Enums.StorageResultType.Success === sResult && oData && !oData.Result) { if (window.parent && !!RL.settingsGet('InIframe')) { window.parent.location.reload(); } else { window.location.reload(); } } }, RL.settingsGet('Version')); }, {}, 60 * 60 * 1000); } _.extend(RainLoopApp.prototype, AbstractApp.prototype); RainLoopApp.prototype.oData = null; RainLoopApp.prototype.oRemote = null; RainLoopApp.prototype.oCache = null; /** * @return {WebMailDataStorage} */ RainLoopApp.prototype.data = function () { if (null === this.oData) { this.oData = new WebMailDataStorage(); } return this.oData; }; /** * @return {WebMailAjaxRemoteStorage} */ RainLoopApp.prototype.remote = function () { if (null === this.oRemote) { this.oRemote = new WebMailAjaxRemoteStorage(); } return this.oRemote; }; RainLoopApp.prototype.reloadFlagsCurrentMessageListAndMessageFromCache = function () { _.each(Data.messageList(), function (oMessage) { Cache.initMessageFlagsFromCache(oMessage); }); Cache.initMessageFlagsFromCache(Data.message()); }; /** * @param {boolean=} bDropPagePosition = false * @param {boolean=} bDropCurrenFolderCache = false */ RainLoopApp.prototype.reloadMessageList = function (bDropPagePosition, bDropCurrenFolderCache) { var iOffset = (Data.messageListPage() - 1) * Data.messagesPerPage() ; if (Utils.isUnd(bDropCurrenFolderCache) ? false : !!bDropCurrenFolderCache) { Cache.setFolderHash(Data.currentFolderFullNameRaw(), ''); } if (Utils.isUnd(bDropPagePosition) ? false : !!bDropPagePosition) { Data.messageListPage(1); iOffset = 0; } Data.messageListLoading(true); Remote.messageList(function (sResult, oData, bCached) { if (Enums.StorageResultType.Success === sResult && oData && oData.Result) { Data.messageListError(''); Data.messageListLoading(false); Data.setMessageList(oData, bCached); } else if (Enums.StorageResultType.Unload === sResult) { Data.messageListError(''); Data.messageListLoading(false); } else if (Enums.StorageResultType.Abort !== sResult) { Data.messageList([]); Data.messageListLoading(false); Data.messageListError(oData && oData.ErrorCode ? Utils.getNotification(oData.ErrorCode) : Utils.i18n('NOTIFICATIONS/CANT_GET_MESSAGE_LIST') ); } }, Data.currentFolderFullNameRaw(), iOffset, Data.messagesPerPage(), Data.messageListSearch()); }; RainLoopApp.prototype.recacheInboxMessageList = function () { Remote.messageList(Utils.emptyFunction, 'INBOX', 0, Data.messagesPerPage(), '', true); }; RainLoopApp.prototype.reloadMessageListHelper = function (bEmptyList) { RL.reloadMessageList(bEmptyList); }; /** * @param {Function} fResultFunc * @returns {boolean} */ RainLoopApp.prototype.contactsSync = function (fResultFunc) { var oContacts = Data.contacts; if (oContacts.importing() || oContacts.syncing() || !Data.enableContactsSync() || !Data.allowContactsSync()) { return false; } oContacts.syncing(true); Remote.contactsSync(function (sResult, oData) { oContacts.syncing(false); if (fResultFunc) { fResultFunc(sResult, oData); } }); return true; }; RainLoopApp.prototype.messagesMoveTrigger = function () { var self = this, sSpamFolder = Data.spamFolder() ; _.each(this.oMoveCache, function (oItem) { var bSpam = sSpamFolder === oItem['To'], bHam = !bSpam && sSpamFolder === oItem['From'] && 'INBOX' === oItem['To'] ; Remote.messagesMove(self.moveOrDeleteResponseHelper, oItem['From'], oItem['To'], oItem['Uid'], bSpam ? 'SPAM' : (bHam ? 'HAM' : '')); }); this.oMoveCache = {}; }; RainLoopApp.prototype.messagesMoveHelper = function (sFromFolderFullNameRaw, sToFolderFullNameRaw, aUidForMove) { var sH = '$$' + sFromFolderFullNameRaw + '$$' + sToFolderFullNameRaw + '$$'; if (!this.oMoveCache[sH]) { this.oMoveCache[sH] = { 'From': sFromFolderFullNameRaw, 'To': sToFolderFullNameRaw, 'Uid': [] }; } this.oMoveCache[sH]['Uid'] = _.union(this.oMoveCache[sH]['Uid'], aUidForMove); this.messagesMoveTrigger(); }; RainLoopApp.prototype.messagesCopyHelper = function (sFromFolderFullNameRaw, sToFolderFullNameRaw, aUidForCopy) { Remote.messagesCopy( this.moveOrDeleteResponseHelper, sFromFolderFullNameRaw, sToFolderFullNameRaw, aUidForCopy ); }; RainLoopApp.prototype.messagesDeleteHelper = function (sFromFolderFullNameRaw, aUidForRemove) { Remote.messagesDelete( this.moveOrDeleteResponseHelper, sFromFolderFullNameRaw, aUidForRemove ); }; RainLoopApp.prototype.moveOrDeleteResponseHelper = function (sResult, oData) { if (Enums.StorageResultType.Success === sResult && Data.currentFolder()) { if (oData && Utils.isArray(oData.Result) && 2 === oData.Result.length) { Cache.setFolderHash(oData.Result[0], oData.Result[1]); } else { Cache.setFolderHash(Data.currentFolderFullNameRaw(), ''); if (oData && -1 < Utils.inArray(oData.ErrorCode, [Enums.Notification.CantMoveMessage, Enums.Notification.CantCopyMessage])) { window.alert(Utils.getNotification(oData.ErrorCode)); } } RL.reloadMessageListHelper(0 === Data.messageList().length); RL.quotaDebounce(); } }; /** * @param {string} sFromFolderFullNameRaw * @param {Array} aUidForRemove */ RainLoopApp.prototype.deleteMessagesFromFolderWithoutCheck = function (sFromFolderFullNameRaw, aUidForRemove) { this.messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove); Data.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove); }; /** * @param {number} iDeleteType * @param {string} sFromFolderFullNameRaw * @param {Array} aUidForRemove * @param {boolean=} bUseFolder = true */ RainLoopApp.prototype.deleteMessagesFromFolder = function (iDeleteType, sFromFolderFullNameRaw, aUidForRemove, bUseFolder) { var self = this, oMoveFolder = null, nSetSystemFoldersNotification = null ; switch (iDeleteType) { case Enums.FolderType.Spam: oMoveFolder = Cache.getFolderFromCacheList(Data.spamFolder()); nSetSystemFoldersNotification = Enums.SetSystemFoldersNotification.Spam; break; case Enums.FolderType.NotSpam: oMoveFolder = Cache.getFolderFromCacheList('INBOX'); break; case Enums.FolderType.Trash: oMoveFolder = Cache.getFolderFromCacheList(Data.trashFolder()); nSetSystemFoldersNotification = Enums.SetSystemFoldersNotification.Trash; break; case Enums.FolderType.Archive: oMoveFolder = Cache.getFolderFromCacheList(Data.archiveFolder()); nSetSystemFoldersNotification = Enums.SetSystemFoldersNotification.Archive; break; } bUseFolder = Utils.isUnd(bUseFolder) ? true : !!bUseFolder; if (bUseFolder) { if ((Enums.FolderType.Spam === iDeleteType && Consts.Values.UnuseOptionValue === Data.spamFolder()) || (Enums.FolderType.Trash === iDeleteType && Consts.Values.UnuseOptionValue === Data.trashFolder()) || (Enums.FolderType.Archive === iDeleteType && Consts.Values.UnuseOptionValue === Data.archiveFolder())) { bUseFolder = false; } } if (!oMoveFolder && bUseFolder) { kn.showScreenPopup(PopupsFolderSystemViewModel, [nSetSystemFoldersNotification]); } else if (!bUseFolder || (Enums.FolderType.Trash === iDeleteType && (sFromFolderFullNameRaw === Data.spamFolder() || sFromFolderFullNameRaw === Data.trashFolder()))) { kn.showScreenPopup(PopupsAskViewModel, [Utils.i18n('POPUPS_ASK/DESC_WANT_DELETE_MESSAGES'), function () { self.messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove); Data.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove); }]); } else if (oMoveFolder) { this.messagesMoveHelper(sFromFolderFullNameRaw, oMoveFolder.fullNameRaw, aUidForRemove); Data.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove, oMoveFolder.fullNameRaw); } }; /** * @param {string} sFromFolderFullNameRaw * @param {Array} aUidForMove * @param {string} sToFolderFullNameRaw * @param {boolean=} bCopy = false */ RainLoopApp.prototype.moveMessagesToFolder = function (sFromFolderFullNameRaw, aUidForMove, sToFolderFullNameRaw, bCopy) { if (sFromFolderFullNameRaw !== sToFolderFullNameRaw && Utils.isArray(aUidForMove) && 0 < aUidForMove.length) { var oFromFolder = Cache.getFolderFromCacheList(sFromFolderFullNameRaw), oToFolder = Cache.getFolderFromCacheList(sToFolderFullNameRaw) ; if (oFromFolder && oToFolder) { if (Utils.isUnd(bCopy) ? false : !!bCopy) { this.messagesCopyHelper(oFromFolder.fullNameRaw, oToFolder.fullNameRaw, aUidForMove); } else { this.messagesMoveHelper(oFromFolder.fullNameRaw, oToFolder.fullNameRaw, aUidForMove); } Data.removeMessagesFromList(oFromFolder.fullNameRaw, aUidForMove, oToFolder.fullNameRaw, bCopy); return true; } } return false; }; /** * @param {Function=} fCallback */ RainLoopApp.prototype.folders = function (fCallback) { this.data().foldersLoading(true); this.remote().folders(_.bind(function (sResult, oData) { Data.foldersLoading(false); if (Enums.StorageResultType.Success === sResult) { this.data().setFolders(oData); if (fCallback) { fCallback(true); } } else { if (fCallback) { fCallback(false); } } }, this)); }; RainLoopApp.prototype.reloadOpenPgpKeys = function () { if (Data.capaOpenPGP()) { var aKeys = [], oEmail = new EmailModel(), oOpenpgpKeyring = Data.openpgpKeyring, oOpenpgpKeys = oOpenpgpKeyring ? oOpenpgpKeyring.getAllKeys() : [] ; _.each(oOpenpgpKeys, function (oItem, iIndex) { if (oItem && oItem.primaryKey) { var oPrimaryUser = oItem.getPrimaryUser(), sUser = (oPrimaryUser && oPrimaryUser.user) ? oPrimaryUser.user.userId.userid : (oItem.users && oItem.users[0] ? oItem.users[0].userId.userid : '') ; oEmail.clear(); oEmail.mailsoParse(sUser); if (oEmail.validate()) { aKeys.push(new OpenPgpKeyModel( iIndex, oItem.primaryKey.getFingerprint(), oItem.primaryKey.getKeyId().toHex().toLowerCase(), sUser, oEmail.email, oItem.isPrivate(), oItem.armor()) ); } } }); Data.openpgpkeys(aKeys); } }; RainLoopApp.prototype.accountsAndIdentities = function () { Data.accountsLoading(true); Data.identitiesLoading(true); Remote.accountsAndIdentities(function (sResult, oData) { Data.accountsLoading(false); Data.identitiesLoading(false); if (Enums.StorageResultType.Success === sResult && oData.Result) { var sParentEmail = RL.settingsGet('ParentEmail'), sAccountEmail = Data.accountEmail() ; sParentEmail = '' === sParentEmail ? sAccountEmail : sParentEmail; if (Utils.isArray(oData.Result['Accounts'])) { Data.accounts(_.map(oData.Result['Accounts'], function (sValue) { return new AccountModel(sValue, sValue !== sParentEmail); })); } if (Utils.isArray(oData.Result['Identities'])) { Data.identities(_.map(oData.Result['Identities'], function (oIdentityData) { var sId = Utils.pString(oIdentityData['Id']), sEmail = Utils.pString(oIdentityData['Email']), oIdentity = new IdentityModel(sId, sEmail, sId !== sAccountEmail) ; oIdentity.name(Utils.pString(oIdentityData['Name'])); oIdentity.replyTo(Utils.pString(oIdentityData['ReplyTo'])); oIdentity.bcc(Utils.pString(oIdentityData['Bcc'])); return oIdentity; })); } } }); }; RainLoopApp.prototype.quota = function () { this.remote().quota(function (sResult, oData) { if (Enums.StorageResultType.Success === sResult && oData && oData.Result && Utils.isArray(oData.Result) && 1 < oData.Result.length && Utils.isPosNumeric(oData.Result[0], true) && Utils.isPosNumeric(oData.Result[1], true)) { Data.userQuota(Utils.pInt(oData.Result[1]) * 1024); Data.userUsageSize(Utils.pInt(oData.Result[0]) * 1024); } }); }; /** * @param {string} sFolder * @param {Array=} aList = [] */ RainLoopApp.prototype.folderInformation = function (sFolder, aList) { if ('' !== Utils.trim(sFolder)) { this.remote().folderInformation(function (sResult, oData) { if (Enums.StorageResultType.Success === sResult) { if (oData && oData.Result && oData.Result.Hash && oData.Result.Folder) { var iUtc = moment().unix(), sHash = Cache.getFolderHash(oData.Result.Folder), oFolder = Cache.getFolderFromCacheList(oData.Result.Folder), bCheck = false, sUid = '', aList = [], bUnreadCountChange = false, oFlags = null ; if (oFolder) { oFolder.interval = iUtc; if (oData.Result.Hash) { Cache.setFolderHash(oData.Result.Folder, oData.Result.Hash); } if (Utils.isNormal(oData.Result.MessageCount)) { oFolder.messageCountAll(oData.Result.MessageCount); } if (Utils.isNormal(oData.Result.MessageUnseenCount)) { if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oData.Result.MessageUnseenCount)) { bUnreadCountChange = true; } oFolder.messageCountUnread(oData.Result.MessageUnseenCount); } if (bUnreadCountChange) { Cache.clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw); } if (oData.Result.Flags) { for (sUid in oData.Result.Flags) { if (oData.Result.Flags.hasOwnProperty(sUid)) { bCheck = true; oFlags = oData.Result.Flags[sUid]; Cache.storeMessageFlagsToCacheByFolderAndUid(oFolder.fullNameRaw, sUid.toString(), [ !oFlags['IsSeen'], !!oFlags['IsFlagged'], !!oFlags['IsAnswered'], !!oFlags['IsForwarded'], !!oFlags['IsReadReceipt'] ]); } } if (bCheck) { RL.reloadFlagsCurrentMessageListAndMessageFromCache(); } } Data.initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages); if (oData.Result.Hash !== sHash || '' === sHash) { if (oFolder.fullNameRaw === Data.currentFolderFullNameRaw()) { RL.reloadMessageList(); } else if ('INBOX' === oFolder.fullNameRaw) { RL.recacheInboxMessageList(); } } else if (bUnreadCountChange) { if (oFolder.fullNameRaw === Data.currentFolderFullNameRaw()) { aList = Data.messageList(); if (Utils.isNonEmptyArray(aList)) { RL.folderInformation(oFolder.fullNameRaw, aList); } } } } } } }, sFolder, aList); } }; /** * @param {boolean=} bBoot = false */ RainLoopApp.prototype.folderInformationMultiply = function (bBoot) { bBoot = Utils.isUnd(bBoot) ? false : !!bBoot; var iUtc = moment().unix(), aFolders = Data.getNextFolderNames(bBoot) ; if (Utils.isNonEmptyArray(aFolders)) { this.remote().folderInformationMultiply(function (sResult, oData) { if (Enums.StorageResultType.Success === sResult) { if (oData && oData.Result && oData.Result.List && Utils.isNonEmptyArray(oData.Result.List)) { _.each(oData.Result.List, function (oItem) { var aList = [], sHash = Cache.getFolderHash(oItem.Folder), oFolder = Cache.getFolderFromCacheList(oItem.Folder), bUnreadCountChange = false ; if (oFolder) { oFolder.interval = iUtc; if (oItem.Hash) { Cache.setFolderHash(oItem.Folder, oItem.Hash); } if (Utils.isNormal(oItem.MessageCount)) { oFolder.messageCountAll(oItem.MessageCount); } if (Utils.isNormal(oItem.MessageUnseenCount)) { if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oItem.MessageUnseenCount)) { bUnreadCountChange = true; } oFolder.messageCountUnread(oItem.MessageUnseenCount); } if (bUnreadCountChange) { Cache.clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw); } if (oItem.Hash !== sHash || '' === sHash) { if (oFolder.fullNameRaw === Data.currentFolderFullNameRaw()) { RL.reloadMessageList(); } } else if (bUnreadCountChange) { if (oFolder.fullNameRaw === Data.currentFolderFullNameRaw()) { aList = Data.messageList(); if (Utils.isNonEmptyArray(aList)) { RL.folderInformation(oFolder.fullNameRaw, aList); } } } } }); if (bBoot) { RL.folderInformationMultiply(true); } } } }, aFolders); } }; RainLoopApp.prototype.setMessageSeen = function (oMessage) { if (oMessage.unseen()) { oMessage.unseen(false); var oFolder = Cache.getFolderFromCacheList(oMessage.folderFullNameRaw); if (oFolder) { oFolder.messageCountUnread(0 <= oFolder.messageCountUnread() - 1 ? oFolder.messageCountUnread() - 1 : 0); } Cache.storeMessageFlagsToCache(oMessage); RL.reloadFlagsCurrentMessageListAndMessageFromCache(); } Remote.messageSetSeen(Utils.emptyFunction, oMessage.folderFullNameRaw, [oMessage.uid], true); }; RainLoopApp.prototype.googleConnect = function () { window.open(LinkBuilder.socialGoogle(), 'Google', 'left=200,top=100,width=650,height=600,menubar=no,status=no,resizable=yes,scrollbars=yes'); }; RainLoopApp.prototype.twitterConnect = function () { window.open(LinkBuilder.socialTwitter(), 'Twitter', 'left=200,top=100,width=650,height=350,menubar=no,status=no,resizable=yes,scrollbars=yes'); }; RainLoopApp.prototype.facebookConnect = function () { window.open(LinkBuilder.socialFacebook(), 'Facebook', 'left=200,top=100,width=650,height=335,menubar=no,status=no,resizable=yes,scrollbars=yes'); }; /** * @param {boolean=} bFireAllActions */ RainLoopApp.prototype.socialUsers = function (bFireAllActions) { if (bFireAllActions) { Data.googleActions(true); Data.facebookActions(true); Data.twitterActions(true); } Remote.socialUsers(function (sResult, oData) { if (Enums.StorageResultType.Success === sResult && oData && oData.Result) { Data.googleUserName(oData.Result['Google'] || ''); Data.facebookUserName(oData.Result['Facebook'] || ''); Data.twitterUserName(oData.Result['Twitter'] || ''); } else { Data.googleUserName(''); Data.facebookUserName(''); Data.twitterUserName(''); } Data.googleLoggined('' !== Data.googleUserName()); Data.facebookLoggined('' !== Data.facebookUserName()); Data.twitterLoggined('' !== Data.twitterUserName()); Data.googleActions(false); Data.facebookActions(false); Data.twitterActions(false); }); }; RainLoopApp.prototype.googleDisconnect = function () { Data.googleActions(true); Remote.googleDisconnect(function () { RL.socialUsers(); }); }; RainLoopApp.prototype.facebookDisconnect = function () { Data.facebookActions(true); Remote.facebookDisconnect(function () { RL.socialUsers(); }); }; RainLoopApp.prototype.twitterDisconnect = function () { Data.twitterActions(true); Remote.twitterDisconnect(function () { RL.socialUsers(); }); }; /** * @param {Array} aSystem * @param {Array} aList * @param {Array=} aDisabled * @param {Array=} aHeaderLines * @param {?number=} iUnDeep * @param {Function=} fDisableCallback * @param {Function=} fVisibleCallback * @param {Function=} fRenameCallback * @param {boolean=} bSystem * @param {boolean=} bBuildUnvisible * @return {Array} */ RainLoopApp.prototype.folderListOptionsBuilder = function (aSystem, aList, aDisabled, aHeaderLines, iUnDeep, fDisableCallback, fVisibleCallback, fRenameCallback, bSystem, bBuildUnvisible) { var iIndex = 0, iLen = 0, /** * @type {?FolderModel} */ oItem = null, bSep = false, sDeepPrefix = '\u00A0\u00A0\u00A0', aResult = [] ; bSystem = !Utils.isNormal(bSystem) ? 0 < aSystem.length : bSystem; bBuildUnvisible = Utils.isUnd(bBuildUnvisible) ? false : !!bBuildUnvisible; iUnDeep = !Utils.isNormal(iUnDeep) ? 0 : iUnDeep; fDisableCallback = Utils.isNormal(fDisableCallback) ? fDisableCallback : null; fVisibleCallback = Utils.isNormal(fVisibleCallback) ? fVisibleCallback : null; fRenameCallback = Utils.isNormal(fRenameCallback) ? fRenameCallback : null; if (!Utils.isArray(aDisabled)) { aDisabled = []; } if (!Utils.isArray(aHeaderLines)) { aHeaderLines = []; } for (iIndex = 0, iLen = aHeaderLines.length; iIndex < iLen; iIndex++) { aResult.push({ 'id': aHeaderLines[iIndex][0], 'name': aHeaderLines[iIndex][1], 'system': false, 'seporator': false, 'disabled': false }); } bSep = true; for (iIndex = 0, iLen = aSystem.length; iIndex < iLen; iIndex++) { oItem = aSystem[iIndex]; if (fVisibleCallback ? fVisibleCallback.call(null, oItem) : true) { if (bSep && 0 < aResult.length) { aResult.push({ 'id': '---', 'name': '---', 'system': false, 'seporator': true, 'disabled': true }); } bSep = false; aResult.push({ 'id': oItem.fullNameRaw, 'name': fRenameCallback ? fRenameCallback.call(null, oItem) : oItem.name(), 'system': true, 'seporator': false, 'disabled': !oItem.selectable || -1 < Utils.inArray(oItem.fullNameRaw, aDisabled) || (fDisableCallback ? fDisableCallback.call(null, oItem) : false) }); } } bSep = true; for (iIndex = 0, iLen = aList.length; iIndex < iLen; iIndex++) { oItem = aList[iIndex]; if (oItem.subScribed() || !oItem.existen) { if (fVisibleCallback ? fVisibleCallback.call(null, oItem) : true) { if (Enums.FolderType.User === oItem.type() || !bSystem || 0 < oItem.subFolders().length) { if (bSep && 0 < aResult.length) { aResult.push({ 'id': '---', 'name': '---', 'system': false, 'seporator': true, 'disabled': true }); } bSep = false; aResult.push({ 'id': oItem.fullNameRaw, 'name': (new window.Array(oItem.deep + 1 - iUnDeep)).join(sDeepPrefix) + (fRenameCallback ? fRenameCallback.call(null, oItem) : oItem.name()), 'system': false, 'seporator': false, 'disabled': !oItem.selectable || -1 < Utils.inArray(oItem.fullNameRaw, aDisabled) || (fDisableCallback ? fDisableCallback.call(null, oItem) : false) }); } } } if (oItem.subScribed() && 0 < oItem.subFolders().length) { aResult = aResult.concat(RL.folderListOptionsBuilder([], oItem.subFolders(), aDisabled, [], iUnDeep, fDisableCallback, fVisibleCallback, fRenameCallback, bSystem, bBuildUnvisible)); } } return aResult; }; /** * @param {string} sQuery * @param {Function} fCallback */ RainLoopApp.prototype.getAutocomplete = function (sQuery, fCallback) { var aData = [] ; Remote.suggestions(function (sResult, oData) { if (Enums.StorageResultType.Success === sResult && oData && Utils.isArray(oData.Result)) { aData = _.map(oData.Result, function (aItem) { return aItem && aItem[0] ? new EmailModel(aItem[0], aItem[1]) : null; }); fCallback(_.compact(aData)); } else if (Enums.StorageResultType.Abort !== sResult) { fCallback([]); } }, sQuery); }; /** * @param {string} sQuery * @param {Function} fCallback */ RainLoopApp.prototype.getContactTagsAutocomplete = function (sQuery, fCallback) { fCallback(_.filter(Data.contactTags(), function (oContactTag) { return oContactTag && oContactTag.filterHelper(sQuery); })); }; /** * @param {string} sMailToUrl * @returns {boolean} */ RainLoopApp.prototype.mailToHelper = function (sMailToUrl) { if (sMailToUrl && 'mailto:' === sMailToUrl.toString().substr(0, 7).toLowerCase()) { sMailToUrl = sMailToUrl.toString().substr(7); var oParams = {}, oEmailModel = null, sEmail = sMailToUrl.replace(/\?.+$/, ''), sQueryString = sMailToUrl.replace(/^[^\?]*\?/, '') ; oEmailModel = new EmailModel(); oEmailModel.parse(window.decodeURIComponent(sEmail)); if (oEmailModel && oEmailModel.email) { oParams = Utils.simpleQueryParser(sQueryString); kn.showScreenPopup(PopupsComposeViewModel, [Enums.ComposeType.Empty, null, [oEmailModel], Utils.isUnd(oParams.subject) ? null : Utils.pString(oParams.subject), Utils.isUnd(oParams.body) ? null : Utils.plainToHtml(Utils.pString(oParams.body)) ]); } return true; } return false; }; RainLoopApp.prototype.bootstart = function () { RL.pub('rl.bootstart'); AbstractApp.prototype.bootstart.call(this); Data.populateDataOnStart(); var sCustomLoginLink = '', sJsHash = RL.settingsGet('JsHash'), iContactsSyncInterval = Utils.pInt(RL.settingsGet('ContactsSyncInterval')), bGoogle = RL.settingsGet('AllowGoogleSocial'), bFacebook = RL.settingsGet('AllowFacebookSocial'), bTwitter = RL.settingsGet('AllowTwitterSocial') ; if (!RL.settingsGet('ChangePasswordIsAllowed')) { kn.removeSettingsViewModel(SettingsChangePasswordScreen); } if (!RL.settingsGet('ContactsIsAllowed')) { kn.removeSettingsViewModel(SettingsContacts); } if (!RL.capa(Enums.Capa.AdditionalAccounts)) { kn.removeSettingsViewModel(SettingsAccounts); } if (RL.capa(Enums.Capa.AdditionalIdentities)) { kn.removeSettingsViewModel(SettingsIdentity); } else { kn.removeSettingsViewModel(SettingsIdentities); } if (!RL.capa(Enums.Capa.OpenPGP)) { kn.removeSettingsViewModel(SettingsOpenPGP); } if (!RL.capa(Enums.Capa.TwoFactor)) { kn.removeSettingsViewModel(SettingsSecurity); } if (!RL.capa(Enums.Capa.Themes)) { kn.removeSettingsViewModel(SettingsThemes); } if (!RL.capa(Enums.Capa.Filters)) { kn.removeSettingsViewModel(SettingsFilters); } if (!bGoogle && !bFacebook && !bTwitter) { kn.removeSettingsViewModel(SettingsSocialScreen); } Utils.initOnStartOrLangChange(function () { $.extend(true, $.magnificPopup.defaults, { 'tClose': Utils.i18n('MAGNIFIC_POPUP/CLOSE'), 'tLoading': Utils.i18n('MAGNIFIC_POPUP/LOADING'), 'gallery': { 'tPrev': Utils.i18n('MAGNIFIC_POPUP/GALLERY_PREV'), 'tNext': Utils.i18n('MAGNIFIC_POPUP/GALLERY_NEXT'), 'tCounter': Utils.i18n('MAGNIFIC_POPUP/GALLERY_COUNTER') }, 'image': { 'tError': Utils.i18n('MAGNIFIC_POPUP/IMAGE_ERROR') }, 'ajax': { 'tError': Utils.i18n('MAGNIFIC_POPUP/AJAX_ERROR') } }); }, this); if (window.SimplePace) { window.SimplePace.set(70); window.SimplePace.sleep(); } if (!!RL.settingsGet('Auth')) { this.setTitle(Utils.i18n('TITLES/LOADING')); this.folders(_.bind(function (bValue) { kn.hideLoading(); if (bValue) { if (window.$LAB && window.crypto && window.crypto.getRandomValues && RL.capa(Enums.Capa.OpenPGP)) { window.$LAB.script(window.openpgp ? '' : LinkBuilder.openPgpJs()).wait(function () { if (window.openpgp) { Data.openpgpKeyring = new window.openpgp.Keyring(); Data.capaOpenPGP(true); RL.pub('openpgp.init'); RL.reloadOpenPgpKeys(); } }); } else { Data.capaOpenPGP(false); } kn.startScreens([MailBoxScreen, SettingsScreen]); if (bGoogle || bFacebook || bTwitter) { RL.socialUsers(true); } RL.sub('interval.2m', function () { RL.folderInformation('INBOX'); }); RL.sub('interval.2m', function () { var sF = Data.currentFolderFullNameRaw(); if ('INBOX' !== sF) { RL.folderInformation(sF); } }); RL.sub('interval.3m', function () { RL.folderInformationMultiply(); }); RL.sub('interval.5m', function () { RL.quota(); }); RL.sub('interval.10m', function () { RL.folders(); }); iContactsSyncInterval = 5 <= iContactsSyncInterval ? iContactsSyncInterval : 20; iContactsSyncInterval = 320 >= iContactsSyncInterval ? iContactsSyncInterval : 320; window.setInterval(function () { RL.contactsSync(); }, iContactsSyncInterval * 60000 + 5000); _.delay(function () { RL.contactsSync(); }, 5000); _.delay(function () { RL.folderInformationMultiply(true); }, 500); Plugins.runHook('rl-start-user-screens'); RL.pub('rl.bootstart-user-screens'); if (!!RL.settingsGet('AccountSignMe') && window.navigator.registerProtocolHandler) { _.delay(function () { try { window.navigator.registerProtocolHandler('mailto', window.location.protocol + '//' + window.location.host + window.location.pathname + '?mailto&to=%s', '' + (RL.settingsGet('Title') || 'RainLoop')); } catch(e) {} if (RL.settingsGet('MailToEmail')) { RL.mailToHelper(RL.settingsGet('MailToEmail')); } }, 500); } } else { kn.startScreens([LoginScreen]); Plugins.runHook('rl-start-login-screens'); RL.pub('rl.bootstart-login-screens'); } if (window.SimplePace) { window.SimplePace.set(100); } if (!Globals.bMobileDevice) { _.defer(function () { Utils.initLayoutResizer('#rl-left', '#rl-right', Enums.ClientSideKeyName.FolderListSize); }); } }, this)); } else { sCustomLoginLink = Utils.pString(RL.settingsGet('CustomLoginLink')); if (!sCustomLoginLink) { kn.hideLoading(); kn.startScreens([LoginScreen]); Plugins.runHook('rl-start-login-screens'); RL.pub('rl.bootstart-login-screens'); if (window.SimplePace) { window.SimplePace.set(100); } } else { kn.routeOff(); kn.setHash(LinkBuilder.root(), true); kn.routeOff(); _.defer(function () { window.location.href = sCustomLoginLink; }); } } if (bGoogle) { window['rl_' + sJsHash + '_google_service'] = function () { Data.googleActions(true); RL.socialUsers(); }; } if (bFacebook) { window['rl_' + sJsHash + '_facebook_service'] = function () { Data.facebookActions(true); RL.socialUsers(); }; } if (bTwitter) { window['rl_' + sJsHash + '_twitter_service'] = function () { Data.twitterActions(true); RL.socialUsers(); }; } RL.sub('interval.1m', function () { Globals.momentTrigger(!Globals.momentTrigger()); }); Plugins.runHook('rl-start-screens'); RL.pub('rl.bootstart-end'); }; module.exports = new RainLoopApp(); }(module)); },{"../Common/Consts.js":4,"../Common/Enums.js":5,"../Common/Globals.js":6,"../Common/LinkBuilder.js":7,"../Common/Plugins.js":8,"../Common/Utils.js":9,"../External/jquery.js":19,"../External/moment.js":22,"../External/underscore.js":24,"../External/window.js":25,"../Knoin/Knoin.js":26,"../Storages/WebMailAjaxRemoteStorage.js":39,"../Storages/WebMailCacheStorage.js":40,"../Storages/WebMailDataStorage.js":41,"../ViewModels/Popups/PopupsAskViewModel.js":42,"./AbstractApp.js":2}],4:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ (function (module) { 'use strict'; var Consts = {}; Consts.Values = {}; Consts.DataImages = {}; Consts.Defaults = {}; /** * @const * @type {number} */ Consts.Defaults.MessagesPerPage = 20; /** * @const * @type {number} */ Consts.Defaults.ContactsPerPage = 50; /** * @const * @type {Array} */ Consts.Defaults.MessagesPerPageArray = [10, 20, 30, 50, 100/*, 150, 200, 300*/]; /** * @const * @type {number} */ Consts.Defaults.DefaultAjaxTimeout = 30000; /** * @const * @type {number} */ Consts.Defaults.SearchAjaxTimeout = 300000; /** * @const * @type {number} */ Consts.Defaults.SendMessageAjaxTimeout = 300000; /** * @const * @type {number} */ Consts.Defaults.SaveMessageAjaxTimeout = 200000; /** * @const * @type {number} */ Consts.Defaults.ContactsSyncAjaxTimeout = 200000; /** * @const * @type {string} */ Consts.Values.UnuseOptionValue = '__UNUSE__'; /** * @const * @type {string} */ Consts.Values.ClientSideCookieIndexName = 'rlcsc'; /** * @const * @type {number} */ Consts.Values.ImapDefaulPort = 143; /** * @const * @type {number} */ Consts.Values.ImapDefaulSecurePort = 993; /** * @const * @type {number} */ Consts.Values.SmtpDefaulPort = 25; /** * @const * @type {number} */ Consts.Values.SmtpDefaulSecurePort = 465; /** * @const * @type {number} */ Consts.Values.MessageBodyCacheLimit = 15; /** * @const * @type {number} */ Consts.Values.AjaxErrorLimit = 7; /** * @const * @type {number} */ Consts.Values.TokenErrorLimit = 10; /** * @const * @type {string} */ Consts.DataImages.UserDotPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2P8DwQACgAD/il4QJ8AAAAASUVORK5CYII='; /** * @const * @type {string} */ Consts.DataImages.TranspPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2NkAAIAAAoAAggA9GkAAAAASUVORK5CYII='; module.exports = Consts; }(module)); },{}],5:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ (function (module) { 'use strict'; var Enums = {}; /** * @enum {string} */ Enums.StorageResultType = { 'Success': 'success', 'Abort': 'abort', 'Error': 'error', 'Unload': 'unload' }; /** * @enum {number} */ Enums.State = { 'Empty': 10, 'Login': 20, 'Auth': 30 }; /** * @enum {number} */ Enums.StateType = { 'Webmail': 0, 'Admin': 1 }; /** * @enum {string} */ Enums.Capa = { 'Prem': 'PREM', 'TwoFactor': 'TWO_FACTOR', 'OpenPGP': 'OPEN_PGP', 'Prefetch': 'PREFETCH', 'Gravatar': 'GRAVATAR', 'Themes': 'THEMES', 'Filters': 'FILTERS', 'AdditionalAccounts': 'ADDITIONAL_ACCOUNTS', 'AdditionalIdentities': 'ADDITIONAL_IDENTITIES' }; /** * @enum {string} */ Enums.KeyState = { 'All': 'all', 'None': 'none', 'ContactList': 'contact-list', 'MessageList': 'message-list', 'FolderList': 'folder-list', 'MessageView': 'message-view', 'Compose': 'compose', 'Settings': 'settings', 'Menu': 'menu', 'PopupComposeOpenPGP': 'compose-open-pgp', 'PopupKeyboardShortcutsHelp': 'popup-keyboard-shortcuts-help', 'PopupAsk': 'popup-ask' }; /** * @enum {number} */ Enums.FolderType = { 'Inbox': 10, 'SentItems': 11, 'Draft': 12, 'Trash': 13, 'Spam': 14, 'Archive': 15, 'NotSpam': 80, 'User': 99 }; /** * @enum {string} */ Enums.LoginSignMeTypeAsString = { 'DefaultOff': 'defaultoff', 'DefaultOn': 'defaulton', 'Unused': 'unused' }; /** * @enum {number} */ Enums.LoginSignMeType = { 'DefaultOff': 0, 'DefaultOn': 1, 'Unused': 2 }; /** * @enum {string} */ Enums.ComposeType = { 'Empty': 'empty', 'Reply': 'reply', 'ReplyAll': 'replyall', 'Forward': 'forward', 'ForwardAsAttachment': 'forward-as-attachment', 'Draft': 'draft', 'EditAsNew': 'editasnew' }; /** * @enum {number} */ Enums.UploadErrorCode = { 'Normal': 0, 'FileIsTooBig': 1, 'FilePartiallyUploaded': 2, 'FileNoUploaded': 3, 'MissingTempFolder': 4, 'FileOnSaveingError': 5, 'FileType': 98, 'Unknown': 99 }; /** * @enum {number} */ Enums.SetSystemFoldersNotification = { 'None': 0, 'Sent': 1, 'Draft': 2, 'Spam': 3, 'Trash': 4, 'Archive': 5 }; /** * @enum {number} */ Enums.ClientSideKeyName = { 'FoldersLashHash': 0, 'MessagesInboxLastHash': 1, 'MailBoxListSize': 2, 'ExpandedFolders': 3, 'FolderListSize': 4 }; /** * @enum {number} */ Enums.EventKeyCode = { 'Backspace': 8, 'Tab': 9, 'Enter': 13, 'Esc': 27, 'PageUp': 33, 'PageDown': 34, 'Left': 37, 'Right': 39, 'Up': 38, 'Down': 40, 'End': 35, 'Home': 36, 'Space': 32, 'Insert': 45, 'Delete': 46, 'A': 65, 'S': 83 }; /** * @enum {number} */ Enums.MessageSetAction = { 'SetSeen': 0, 'UnsetSeen': 1, 'SetFlag': 2, 'UnsetFlag': 3 }; /** * @enum {number} */ Enums.MessageSelectAction = { 'All': 0, 'None': 1, 'Invert': 2, 'Unseen': 3, 'Seen': 4, 'Flagged': 5, 'Unflagged': 6 }; /** * @enum {number} */ Enums.DesktopNotifications = { 'Allowed': 0, 'NotAllowed': 1, 'Denied': 2, 'NotSupported': 9 }; /** * @enum {number} */ Enums.MessagePriority = { 'Low': 5, 'Normal': 3, 'High': 1 }; /** * @enum {string} */ Enums.EditorDefaultType = { 'Html': 'Html', 'Plain': 'Plain' }; /** * @enum {string} */ Enums.CustomThemeType = { 'Light': 'Light', 'Dark': 'Dark' }; /** * @enum {number} */ Enums.ServerSecure = { 'None': 0, 'SSL': 1, 'TLS': 2 }; /** * @enum {number} */ Enums.SearchDateType = { 'All': -1, 'Days3': 3, 'Days7': 7, 'Month': 30 }; /** * @enum {number} */ Enums.EmailType = { 'Defailt': 0, 'Facebook': 1, 'Google': 2 }; /** * @enum {number} */ Enums.SaveSettingsStep = { 'Animate': -2, 'Idle': -1, 'TrueResult': 1, 'FalseResult': 0 }; /** * @enum {string} */ Enums.InterfaceAnimation = { 'None': 'None', 'Normal': 'Normal', 'Full': 'Full' }; /** * @enum {number} */ Enums.Layout = { 'NoPreview': 0, 'SidePreview': 1, 'BottomPreview': 2 }; /** * @enum {string} */ Enums.FilterConditionField = { 'From': 'From', 'To': 'To', 'Recipient': 'Recipient', 'Subject': 'Subject' }; /** * @enum {string} */ Enums.FilterConditionType = { 'Contains': 'Contains', 'NotContains': 'NotContains', 'EqualTo': 'EqualTo', 'NotEqualTo': 'NotEqualTo' }; /** * @enum {string} */ Enums.FiltersAction = { 'None': 'None', 'Move': 'Move', 'Discard': 'Discard', 'Forward': 'Forward', }; /** * @enum {string} */ Enums.FilterRulesType = { 'And': 'And', 'Or': 'Or' }; /** * @enum {number} */ Enums.SignedVerifyStatus = { 'UnknownPublicKeys': -4, 'UnknownPrivateKey': -3, 'Unverified': -2, 'Error': -1, 'None': 0, 'Success': 1 }; /** * @enum {number} */ Enums.ContactPropertyType = { 'Unknown': 0, 'FullName': 10, 'FirstName': 15, 'LastName': 16, 'MiddleName': 16, 'Nick': 18, 'NamePrefix': 20, 'NameSuffix': 21, 'Email': 30, 'Phone': 31, 'Web': 32, 'Birthday': 40, 'Facebook': 90, 'Skype': 91, 'GitHub': 92, 'Note': 110, 'Custom': 250 }; /** * @enum {number} */ Enums.Notification = { 'InvalidToken': 101, 'AuthError': 102, 'AccessError': 103, 'ConnectionError': 104, 'CaptchaError': 105, 'SocialFacebookLoginAccessDisable': 106, 'SocialTwitterLoginAccessDisable': 107, 'SocialGoogleLoginAccessDisable': 108, 'DomainNotAllowed': 109, 'AccountNotAllowed': 110, 'AccountTwoFactorAuthRequired': 120, 'AccountTwoFactorAuthError': 121, 'CouldNotSaveNewPassword': 130, 'CurrentPasswordIncorrect': 131, 'NewPasswordShort': 132, 'NewPasswordWeak': 133, 'NewPasswordForbidden': 134, 'ContactsSyncError': 140, 'CantGetMessageList': 201, 'CantGetMessage': 202, 'CantDeleteMessage': 203, 'CantMoveMessage': 204, 'CantCopyMessage': 205, 'CantSaveMessage': 301, 'CantSendMessage': 302, 'InvalidRecipients': 303, 'CantCreateFolder': 400, 'CantRenameFolder': 401, 'CantDeleteFolder': 402, 'CantSubscribeFolder': 403, 'CantUnsubscribeFolder': 404, 'CantDeleteNonEmptyFolder': 405, 'CantSaveSettings': 501, 'CantSavePluginSettings': 502, 'DomainAlreadyExists': 601, 'CantInstallPackage': 701, 'CantDeletePackage': 702, 'InvalidPluginPackage': 703, 'UnsupportedPluginPackage': 704, 'LicensingServerIsUnavailable': 710, 'LicensingExpired': 711, 'LicensingBanned': 712, 'DemoSendMessageError': 750, 'AccountAlreadyExists': 801, 'MailServerError': 901, 'ClientViewError': 902, 'InvalidInputArgument': 903, 'UnknownNotification': 999, 'UnknownError': 999 }; module.exports = Enums; }(module)); },{}],6:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ (function (module) { 'use strict'; var Globals = {}, window = require('../External/window.js'), ko = require('../External/ko.js'), $html = require('../External/$html.js') ; /** * @type {?} */ Globals.now = (new window.Date()).getTime(); /** * @type {?} */ Globals.momentTrigger = ko.observable(true); /** * @type {?} */ Globals.dropdownVisibility = ko.observable(false).extend({'rateLimit': 0}); /** * @type {?} */ Globals.tooltipTrigger = ko.observable(false).extend({'rateLimit': 0}); /** * @type {?} */ Globals.langChangeTrigger = ko.observable(true); /** * @type {number} */ Globals.iAjaxErrorCount = 0; /** * @type {number} */ Globals.iTokenErrorCount = 0; /** * @type {number} */ Globals.iMessageBodyCacheCount = 0; /** * @type {boolean} */ Globals.bUnload = false; /** * @type {string} */ Globals.sUserAgent = (window.navigator.userAgent || '').toLowerCase(); /** * @type {boolean} */ Globals.bIsiOSDevice = -1 < Globals.sUserAgent.indexOf('iphone') || -1 < Globals.sUserAgent.indexOf('ipod') || -1 < Globals.sUserAgent.indexOf('ipad'); /** * @type {boolean} */ Globals.bIsAndroidDevice = -1 < Globals.sUserAgent.indexOf('android'); /** * @type {boolean} */ Globals.bMobileDevice = Globals.bIsiOSDevice || Globals.bIsAndroidDevice; /** * @type {boolean} */ Globals.bDisableNanoScroll = Globals.bMobileDevice; /** * @type {boolean} */ Globals.bAllowPdfPreview = !Globals.bMobileDevice; /** * @type {boolean} */ Globals.bAnimationSupported = !Globals.bMobileDevice && $html.hasClass('csstransitions'); /** * @type {boolean} */ Globals.bXMLHttpRequestSupported = !!window.XMLHttpRequest; /** * @type {string} */ Globals.sAnimationType = ''; /** * @type {Object} */ Globals.oHtmlEditorDefaultConfig = { 'title': false, 'stylesSet': false, 'customConfig': '', 'contentsCss': '', 'toolbarGroups': [ {name: 'spec'}, {name: 'styles'}, {name: 'basicstyles', groups: ['basicstyles', 'cleanup']}, {name: 'colors'}, {name: 'paragraph', groups: ['list', 'indent', 'blocks', 'align']}, {name: 'links'}, {name: 'insert'}, {name: 'others'} // {name: 'document', groups: ['mode', 'document', 'doctools']} ], 'removePlugins': 'contextmenu', //blockquote 'removeButtons': 'Format,Undo,Redo,Cut,Copy,Paste,Anchor,Strike,Subscript,Superscript,Image,SelectAll', 'removeDialogTabs': 'link:advanced;link:target;image:advanced;images:advanced', 'extraPlugins': 'plain', 'allowedContent': true, 'autoParagraph': false, 'font_defaultLabel': 'Arial', 'fontSize_defaultLabel': '13', 'fontSize_sizes': '10/10px;12/12px;13/13px;14/14px;16/16px;18/18px;20/20px;24/24px;28/28px;36/36px;48/48px' }; /** * @type {Object} */ Globals.oHtmlEditorLangsMap = { 'de': 'de', 'es': 'es', 'fr': 'fr', 'hu': 'hu', 'is': 'is', 'it': 'it', 'ko': 'ko', 'ko-kr': 'ko', 'lv': 'lv', 'nl': 'nl', 'no': 'no', 'pl': 'pl', 'pt': 'pt', 'pt-pt': 'pt', 'pt-br': 'pt-br', 'ru': 'ru', 'ro': 'ro', 'zh': 'zh', 'zh-cn': 'zh-cn' }; if (Globals.bAllowPdfPreview && window.navigator && window.navigator.mimeTypes) { Globals.bAllowPdfPreview = !!_.find(window.navigator.mimeTypes, function (oType) { return oType && 'application/pdf' === oType.type; }); } Globals.oI18N = {}, Globals.oNotificationI18N = {}, Globals.aBootstrapDropdowns = [], Globals.aViewModels = { 'settings': [], 'settings-removed': [], 'settings-disabled': [] }; module.exports = Globals; }(module)); },{"../External/$html.js":12,"../External/ko.js":21,"../External/window.js":25}],7:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ (function (module) { 'use strict'; var window = require('../External/window.js'), Utils = require('./Utils.js') ; /** * @constructor */ function LinkBuilder() { this.sBase = '#/'; this.sServer = './?'; this.sVersion = RL.settingsGet('Version'); this.sSpecSuffix = RL.settingsGet('AuthAccountHash') || '0'; this.sStaticPrefix = RL.settingsGet('StaticPrefix') || 'rainloop/v/' + this.sVersion + '/static/'; } /** * @return {string} */ LinkBuilder.prototype.root = function () { return this.sBase; }; /** * @param {string} sDownload * @return {string} */ LinkBuilder.prototype.attachmentDownload = function (sDownload) { return this.sServer + '/Raw/' + this.sSpecSuffix + '/Download/' + sDownload; }; /** * @param {string} sDownload * @return {string} */ LinkBuilder.prototype.attachmentPreview = function (sDownload) { return this.sServer + '/Raw/' + this.sSpecSuffix + '/View/' + sDownload; }; /** * @param {string} sDownload * @return {string} */ LinkBuilder.prototype.attachmentPreviewAsPlain = function (sDownload) { return this.sServer + '/Raw/' + this.sSpecSuffix + '/ViewAsPlain/' + sDownload; }; /** * @return {string} */ LinkBuilder.prototype.upload = function () { return this.sServer + '/Upload/' + this.sSpecSuffix + '/'; }; /** * @return {string} */ LinkBuilder.prototype.uploadContacts = function () { return this.sServer + '/UploadContacts/' + this.sSpecSuffix + '/'; }; /** * @return {string} */ LinkBuilder.prototype.uploadBackground = function () { return this.sServer + '/UploadBackground/' + this.sSpecSuffix + '/'; }; /** * @return {string} */ LinkBuilder.prototype.append = function () { return this.sServer + '/Append/' + this.sSpecSuffix + '/'; }; /** * @param {string} sEmail * @return {string} */ LinkBuilder.prototype.change = function (sEmail) { return this.sServer + '/Change/' + this.sSpecSuffix + '/' + window.encodeURIComponent(sEmail) + '/'; }; /** * @param {string=} sAdd * @return {string} */ LinkBuilder.prototype.ajax = function (sAdd) { return this.sServer + '/Ajax/' + this.sSpecSuffix + '/' + sAdd; }; /** * @param {string} sRequestHash * @return {string} */ LinkBuilder.prototype.messageViewLink = function (sRequestHash) { return this.sServer + '/Raw/' + this.sSpecSuffix + '/ViewAsPlain/' + sRequestHash; }; /** * @param {string} sRequestHash * @return {string} */ LinkBuilder.prototype.messageDownloadLink = function (sRequestHash) { return this.sServer + '/Raw/' + this.sSpecSuffix + '/Download/' + sRequestHash; }; /** * @param {string} sEmail * @return {string} */ LinkBuilder.prototype.avatarLink = function (sEmail) { return this.sServer + '/Raw/0/Avatar/' + window.encodeURIComponent(sEmail) + '/'; // return '//secure.gravatar.com/avatar/' + Utils.md5(sEmail.toLowerCase()) + '.jpg?s=80&d=mm'; }; /** * @return {string} */ LinkBuilder.prototype.inbox = function () { return this.sBase + 'mailbox/Inbox'; }; /** * @return {string} */ LinkBuilder.prototype.messagePreview = function () { return this.sBase + 'mailbox/message-preview'; }; /** * @param {string=} sScreenName * @return {string} */ LinkBuilder.prototype.settings = function (sScreenName) { var sResult = this.sBase + 'settings'; if (!Utils.isUnd(sScreenName) && '' !== sScreenName) { sResult += '/' + sScreenName; } return sResult; }; /** * @param {string} sScreenName * @return {string} */ LinkBuilder.prototype.admin = function (sScreenName) { var sResult = this.sBase; switch (sScreenName) { case 'AdminDomains': sResult += 'domains'; break; case 'AdminSecurity': sResult += 'security'; break; case 'AdminLicensing': sResult += 'licensing'; break; } return sResult; }; /** * @param {string} sFolder * @param {number=} iPage = 1 * @param {string=} sSearch = '' * @return {string} */ LinkBuilder.prototype.mailBox = function (sFolder, iPage, sSearch) { iPage = Utils.isNormal(iPage) ? Utils.pInt(iPage) : 1; sSearch = Utils.pString(sSearch); var sResult = this.sBase + 'mailbox/'; if ('' !== sFolder) { sResult += encodeURI(sFolder); } if (1 < iPage) { sResult = sResult.replace(/[\/]+$/, ''); sResult += '/p' + iPage; } if ('' !== sSearch) { sResult = sResult.replace(/[\/]+$/, ''); sResult += '/' + encodeURI(sSearch); } return sResult; }; /** * @return {string} */ LinkBuilder.prototype.phpInfo = function () { return this.sServer + 'Info'; }; /** * @param {string} sLang * @return {string} */ LinkBuilder.prototype.langLink = function (sLang) { return this.sServer + '/Lang/0/' + encodeURI(sLang) + '/' + this.sVersion + '/'; }; /** * @return {string} */ LinkBuilder.prototype.exportContactsVcf = function () { return this.sServer + '/Raw/' + this.sSpecSuffix + '/ContactsVcf/'; }; /** * @return {string} */ LinkBuilder.prototype.exportContactsCsv = function () { return this.sServer + '/Raw/' + this.sSpecSuffix + '/ContactsCsv/'; }; /** * @return {string} */ LinkBuilder.prototype.emptyContactPic = function () { return this.sStaticPrefix + 'css/images/empty-contact.png'; }; /** * @param {string} sFileName * @return {string} */ LinkBuilder.prototype.sound = function (sFileName) { return this.sStaticPrefix + 'sounds/' + sFileName; }; /** * @param {string} sTheme * @return {string} */ LinkBuilder.prototype.themePreviewLink = function (sTheme) { var sPrefix = 'rainloop/v/' + this.sVersion + '/'; if ('@custom' === sTheme.substr(-7)) { sTheme = Utils.trim(sTheme.substring(0, sTheme.length - 7)); sPrefix = ''; } return sPrefix + 'themes/' + encodeURI(sTheme) + '/images/preview.png'; }; /** * @return {string} */ LinkBuilder.prototype.notificationMailIcon = function () { return this.sStaticPrefix + 'css/images/icom-message-notification.png'; }; /** * @return {string} */ LinkBuilder.prototype.openPgpJs = function () { return this.sStaticPrefix + 'js/openpgp.min.js'; }; /** * @return {string} */ LinkBuilder.prototype.socialGoogle = function () { return this.sServer + 'SocialGoogle' + ('' !== this.sSpecSuffix ? '/' + this.sSpecSuffix + '/' : ''); }; /** * @return {string} */ LinkBuilder.prototype.socialTwitter = function () { return this.sServer + 'SocialTwitter' + ('' !== this.sSpecSuffix ? '/' + this.sSpecSuffix + '/' : ''); }; /** * @return {string} */ LinkBuilder.prototype.socialFacebook = function () { return this.sServer + 'SocialFacebook' + ('' !== this.sSpecSuffix ? '/' + this.sSpecSuffix + '/' : ''); }; module.exports = new LinkBuilder(); }(module)); },{"../External/window.js":25,"./Utils.js":9}],8:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ (function (module) { 'use strict'; var Plugins = {}, Utils = require('./Utils.js'), Remote = require('../Remote.js'), RL = require('../RL.js') ; /** * @type {Object} */ Plugins.oViewModelsHooks = {}; /** * @type {Object} */ Plugins.oSimpleHooks = {}; /** * @param {string} sName * @param {Function} ViewModel */ Plugins.regViewModelHook = function (sName, ViewModel) { if (ViewModel) { ViewModel.__hookName = sName; } }; /** * @param {string} sName * @param {Function} fCallback */ Plugins.addHook = function (sName, fCallback) { if (Utils.isFunc(fCallback)) { if (!Utils.isArray(Plugins.oSimpleHooks[sName])) { Plugins.oSimpleHooks[sName] = []; } Plugins.oSimpleHooks[sName].push(fCallback); } }; /** * @param {string} sName * @param {Array=} aArguments */ Plugins.runHook = function (sName, aArguments) { if (Utils.isArray(Plugins.oSimpleHooks[sName])) { aArguments = aArguments || []; _.each(Plugins.oSimpleHooks[sName], function (fCallback) { fCallback.apply(null, aArguments); }); } }; /** * @param {string} sName * @return {?} */ Plugins.mainSettingsGet = function (sName) { return RL ? RL().settingsGet(sName) : null; }; /** * @param {Function} fCallback * @param {string} sAction * @param {Object=} oParameters * @param {?number=} iTimeout * @param {string=} sGetAdd = '' * @param {Array=} aAbortActions = [] */ Plugins.remoteRequest = function (fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions) { if (Remote) { Remote().defaultRequest(fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions); } }; /** * @param {string} sPluginSection * @param {string} sName * @return {?} */ Plugins.settingsGet = function (sPluginSection, sName) { var oPlugin = Plugins.mainSettingsGet('Plugins'); oPlugin = oPlugin && Utils.isUnd(oPlugin[sPluginSection]) ? null : oPlugin[sPluginSection]; return oPlugin ? (Utils.isUnd(oPlugin[sName]) ? null : oPlugin[sName]) : null; }; module.exports = Plugins; }(module)); },{"../RL.js":32,"../Remote.js":33,"./Utils.js":9}],9:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ (function (module) { 'use strict'; var Utils = {}, $ = require('../External/jquery.js'), _ = require('../External/underscore.js'), ko = require('../External/ko.js'), key = require('../External/key.js'), window = require('../External/window.js'), $window = require('../External/$window.js'), $doc = require('../External/$doc.js'), NotificationClass = require('../External/NotificationClass.js'), LocalStorage = require('../Storages/LocalStorage.js'), kn = require('../Knoin/Knoin.js'), Enums = require('./Enums.js'), Globals = require('./Globals.js') ; Utils.trim = $.trim; Utils.inArray = $.inArray; Utils.isArray = _.isArray; Utils.isFunc = _.isFunction; Utils.isUnd = _.isUndefined; Utils.isNull = _.isNull; Utils.emptyFunction = function () {}; /** * @param {*} oValue * @return {boolean} */ Utils.isNormal = function (oValue) { return !Utils.isUnd(oValue) && !Utils.isNull(oValue); }; Utils.windowResize = _.debounce(function (iTimeout) { if (Utils.isUnd(iTimeout)) { $window.resize(); } else { window.setTimeout(function () { $window.resize(); }, iTimeout); } }, 50); /** * @param {(string|number)} mValue * @param {boolean=} bIncludeZero * @return {boolean} */ Utils.isPosNumeric = function (mValue, bIncludeZero) { return Utils.isNormal(mValue) ? ((Utils.isUnd(bIncludeZero) ? true : !!bIncludeZero) ? (/^[0-9]*$/).test(mValue.toString()) : (/^[1-9]+[0-9]*$/).test(mValue.toString())) : false; }; /** * @param {*} iValue * @param {number=} iDefault = 0 * @return {number} */ Utils.pInt = function (iValue, iDefault) { var iResult = Utils.isNormal(iValue) && '' !== iValue ? window.parseInt(iValue, 10) : (iDefault || 0); return window.isNaN(iResult) ? (iDefault || 0) : iResult; }; /** * @param {*} mValue * @return {string} */ Utils.pString = function (mValue) { return Utils.isNormal(mValue) ? '' + mValue : ''; }; /** * @param {*} aValue * @return {boolean} */ Utils.isNonEmptyArray = function (aValue) { return Utils.isArray(aValue) && 0 < aValue.length; }; /** * @param {string} sQueryString * @return {Object} */ Utils.simpleQueryParser = function (sQueryString) { var oParams = {}, aQueries = [], aTemp = [], iIndex = 0, iLen = 0 ; aQueries = sQueryString.split('&'); for (iIndex = 0, iLen = aQueries.length; iIndex < iLen; iIndex++) { aTemp = aQueries[iIndex].split('='); oParams[window.decodeURIComponent(aTemp[0])] = window.decodeURIComponent(aTemp[1]); } return oParams; }; /** * @param {string} aValue * @param {string} sKey * @param {string} sLongKey * @return {string|boolean} */ Utils.rsaEncode = function (sValue, sHash, sKey, sLongKey) { if (window.crypto && window.crypto.getRandomValues && window.RSAKey && sHash && sKey && sLongKey) { var oRsa = new window.RSAKey(); oRsa.setPublic(sLongKey, sKey); sValue = oRsa.encrypt(Utils.fakeMd5() + ':' + sValue + ':' + Utils.fakeMd5()); if (false !== sValue) { return 'rsa:' + sHash + ':' + sValue; } } return false; }; Utils.rsaEncode.supported = !!(window.crypto && window.crypto.getRandomValues && window.RSAKey); /** * @param {string} sPath * @param {*=} oObject * @param {Object=} oObjectToExportTo */ Utils.exportPath = function (sPath, oObject, oObjectToExportTo) { var part = null, parts = sPath.split('.'), cur = oObjectToExportTo || window ; for (; parts.length && (part = parts.shift());) { if (!parts.length && !Utils.isUnd(oObject)) { cur[part] = oObject; } else if (cur[part]) { cur = cur[part]; } else { cur = cur[part] = {}; } } }; /** * @param {Object} oObject * @param {string} sName * @param {*} mValue */ Utils.pImport = function (oObject, sName, mValue) { oObject[sName] = mValue; }; /** * @param {Object} oObject * @param {string} sName * @param {*} mDefault * @return {*} */ Utils.pExport = function (oObject, sName, mDefault) { return Utils.isUnd(oObject[sName]) ? mDefault : oObject[sName]; }; /** * @param {string} sText * @return {string} */ Utils.encodeHtml = function (sText) { return Utils.isNormal(sText) ? sText.toString() .replace(/&/g, '&').replace(//g, '>') .replace(/"/g, '"').replace(/'/g, ''') : ''; }; /** * @param {string} sText * @param {number=} iLen * @return {string} */ Utils.splitPlainText = function (sText, iLen) { var sPrefix = '', sSubText = '', sResult = sText, iSpacePos = 0, iNewLinePos = 0 ; iLen = Utils.isUnd(iLen) ? 100 : iLen; while (sResult.length > iLen) { sSubText = sResult.substring(0, iLen); iSpacePos = sSubText.lastIndexOf(' '); iNewLinePos = sSubText.lastIndexOf('\n'); if (-1 !== iNewLinePos) { iSpacePos = iNewLinePos; } if (-1 === iSpacePos) { iSpacePos = iLen; } sPrefix += sSubText.substring(0, iSpacePos) + '\n'; sResult = sResult.substring(iSpacePos + 1); } return sPrefix + sResult; }; Utils.timeOutAction = (function () { var oTimeOuts = {} ; return function (sAction, fFunction, iTimeOut) { if (Utils.isUnd(oTimeOuts[sAction])) { oTimeOuts[sAction] = 0; } window.clearTimeout(oTimeOuts[sAction]); oTimeOuts[sAction] = window.setTimeout(fFunction, iTimeOut); }; }()); Utils.timeOutActionSecond = (function () { var oTimeOuts = {} ; return function (sAction, fFunction, iTimeOut) { if (!oTimeOuts[sAction]) { oTimeOuts[sAction] = window.setTimeout(function () { fFunction(); oTimeOuts[sAction] = 0; }, iTimeOut); } }; }()); Utils.audio = (function () { var oAudio = false ; return function (sMp3File, sOggFile) { if (false === oAudio) { if (Globals.bIsiOSDevice) { oAudio = null; } else { var bCanPlayMp3 = false, bCanPlayOgg = false, oAudioLocal = window.Audio ? new window.Audio() : null ; if (oAudioLocal && oAudioLocal.canPlayType && oAudioLocal.play) { bCanPlayMp3 = '' !== oAudioLocal.canPlayType('audio/mpeg; codecs="mp3"'); if (!bCanPlayMp3) { bCanPlayOgg = '' !== oAudioLocal.canPlayType('audio/ogg; codecs="vorbis"'); } if (bCanPlayMp3 || bCanPlayOgg) { oAudio = oAudioLocal; oAudio.preload = 'none'; oAudio.loop = false; oAudio.autoplay = false; oAudio.muted = false; oAudio.src = bCanPlayMp3 ? sMp3File : sOggFile; } else { oAudio = null; } } else { oAudio = null; } } } return oAudio; }; }()); /** * @param {(Object|null|undefined)} oObject * @param {string} sProp * @return {boolean} */ Utils.hos = function (oObject, sProp) { return oObject && window.Object && window.Object.hasOwnProperty ? window.Object.hasOwnProperty.call(oObject, sProp) : false; }; /** * @param {string} sKey * @param {Object=} oValueList * @param {string=} sDefaulValue * @return {string} */ Utils.i18n = function (sKey, oValueList, sDefaulValue) { var sValueName = '', sResult = Utils.isUnd(Globals.oI18N[sKey]) ? (Utils.isUnd(sDefaulValue) ? sKey : sDefaulValue) : Globals.oI18N[sKey] ; if (!Utils.isUnd(oValueList) && !Utils.isNull(oValueList)) { for (sValueName in oValueList) { if (Utils.hos(oValueList, sValueName)) { sResult = sResult.replace('%' + sValueName + '%', oValueList[sValueName]); } } } return sResult; }; /** * @param {Object} oElement */ Utils.i18nToNode = function (oElement) { _.defer(function () { $('.i18n', oElement).each(function () { var jqThis = $(this), sKey = '' ; sKey = jqThis.data('i18n-text'); if (sKey) { jqThis.text(Utils.i18n(sKey)); } else { sKey = jqThis.data('i18n-html'); if (sKey) { jqThis.html(Utils.i18n(sKey)); } sKey = jqThis.data('i18n-placeholder'); if (sKey) { jqThis.attr('placeholder', Utils.i18n(sKey)); } sKey = jqThis.data('i18n-title'); if (sKey) { jqThis.attr('title', Utils.i18n(sKey)); } } }); }); }; Utils.i18nReload = function () { if (window['rainloopI18N']) { Globals.oI18N = window['rainloopI18N'] || {}; Utils.i18nToNode($doc); Globals.langChangeTrigger(!Globals.langChangeTrigger()); } window['rainloopI18N'] = null; }; /** * @param {Function} fCallback * @param {Object} oScope * @param {Function=} fLangCallback */ Utils.initOnStartOrLangChange = function (fCallback, oScope, fLangCallback) { if (fCallback) { fCallback.call(oScope); } if (fLangCallback) { Globals.langChangeTrigger.subscribe(function () { if (fCallback) { fCallback.call(oScope); } fLangCallback.call(oScope); }); } else if (fCallback) { Globals.langChangeTrigger.subscribe(fCallback, oScope); } }; /** * @return {boolean} */ Utils.inFocus = function () { if (document.activeElement) { if (Utils.isUnd(document.activeElement.__inFocusCache)) { document.activeElement.__inFocusCache = $(document.activeElement).is('input,textarea,iframe,.cke_editable'); } return !!document.activeElement.__inFocusCache; } return false; }; Utils.removeInFocus = function () { if (document && document.activeElement && document.activeElement.blur) { var oA = $(document.activeElement); if (oA.is('input,textarea')) { document.activeElement.blur(); } } }; Utils.removeSelection = function () { if (window && window.getSelection) { var oSel = window.getSelection(); if (oSel && oSel.removeAllRanges) { oSel.removeAllRanges(); } } else if (document && document.selection && document.selection.empty) { document.selection.empty(); } }; /** * @param {string} sPrefix * @param {string} sSubject * @return {string} */ Utils.replySubjectAdd = function (sPrefix, sSubject) { sPrefix = Utils.trim(sPrefix.toUpperCase()); sSubject = Utils.trim(sSubject.replace(/[\s]+/, ' ')); var iIndex = 0, sResult = '', bDrop = false, sTrimmedPart = '', aSubject = [], aParts = [], bRe = 'RE' === sPrefix, bFwd = 'FWD' === sPrefix, bPrefixIsRe = !bFwd ; if ('' !== sSubject) { bDrop = false; aParts = sSubject.split(':'); for (iIndex = 0; iIndex < aParts.length; iIndex++) { sTrimmedPart = Utils.trim(aParts[iIndex]); if (!bDrop && (/^(RE|FWD)$/i.test(sTrimmedPart) || /^(RE|FWD)[\[\(][\d]+[\]\)]$/i.test(sTrimmedPart)) ) { if (!bRe) { bRe = !!(/^RE/i.test(sTrimmedPart)); } if (!bFwd) { bFwd = !!(/^FWD/i.test(sTrimmedPart)); } } else { aSubject.push(aParts[iIndex]); bDrop = true; } } if (0 < aSubject.length) { sResult = Utils.trim(aSubject.join(':')); } } if (bPrefixIsRe) { bRe = false; } else { bFwd = false; } return Utils.trim( (bPrefixIsRe ? 'Re: ' : 'Fwd: ') + (bRe ? 'Re: ' : '') + (bFwd ? 'Fwd: ' : '') + sResult ); }; /** * @param {string} sSubject * @return {string} */ Utils.fixLongSubject = function (sSubject) { var iLimit = 30, mReg = /^Re([\[\(]([\d]+)[\]\)]|):[\s]{0,3}Re([\[\(]([\d]+)[\]\)]|):/ig, oMatch = null ; sSubject = Utils.trim(sSubject.replace(/[\s]+/, ' ')); do { iLimit--; oMatch = mReg.exec(sSubject); if (!oMatch || Utils.isUnd(oMatch[0])) { oMatch = null; } if (oMatch) { sSubject = sSubject.replace(mReg, 'Re:'); } } while (oMatch || 0 < iLimit); return sSubject.replace(/[\s]+/, ' '); }; /** * @deprecated * @param {string} sPrefix * @param {string} sSubject * @param {boolean=} bFixLongSubject = true * @return {string} */ Utils._replySubjectAdd_ = function (sPrefix, sSubject, bFixLongSubject) { var oMatch = null, sResult = Utils.trim(sSubject) ; if (null !== (oMatch = (new window.RegExp('^' + sPrefix + '[\\s]?\\:(.*)$', 'gi')).exec(sSubject)) && !Utils.isUnd(oMatch[1])) { sResult = sPrefix + '[2]: ' + oMatch[1]; } else if (null !== (oMatch = (new window.RegExp('^(' + sPrefix + '[\\s]?[\\[\\(]?)([\\d]+)([\\]\\)]?[\\s]?\\:.*)$', 'gi')).exec(sSubject)) && !Utils.isUnd(oMatch[1]) && !Utils.isUnd(oMatch[2]) && !Utils.isUnd(oMatch[3])) { sResult = oMatch[1] + (Utils.pInt(oMatch[2]) + 1) + oMatch[3]; } else { sResult = sPrefix + ': ' + sSubject; } sResult = sResult.replace(/[\s]+/g, ' '); sResult = (Utils.isUnd(bFixLongSubject) ? true : bFixLongSubject) ? Utils.fixLongSubject(sResult) : sResult; // sResult = sResult.replace(/^(Re|Fwd)[\s]?\[[\d]+\]:/ig, '$1:'); return sResult; }; /** * @deprecated * @param {string} sSubject * @return {string} */ Utils._fixLongSubject_ = function (sSubject) { var iCounter = 0, oMatch = null ; sSubject = Utils.trim(sSubject.replace(/[\s]+/, ' ')); do { oMatch = /^Re(\[([\d]+)\]|):[\s]{0,3}Re(\[([\d]+)\]|):/ig.exec(sSubject); if (!oMatch || Utils.isUnd(oMatch[0])) { oMatch = null; } if (oMatch) { iCounter = 0; iCounter += Utils.isUnd(oMatch[2]) ? 1 : 0 + Utils.pInt(oMatch[2]); iCounter += Utils.isUnd(oMatch[4]) ? 1 : 0 + Utils.pInt(oMatch[4]); sSubject = sSubject.replace(/^Re(\[[\d]+\]|):[\s]{0,3}Re(\[[\d]+\]|):/gi, 'Re' + (0 < iCounter ? '[' + iCounter + ']' : '') + ':'); } } while (oMatch); sSubject = sSubject.replace(/[\s]+/, ' '); return sSubject; }; /** * @param {number} iNum * @param {number} iDec * @return {number} */ Utils.roundNumber = function (iNum, iDec) { return Math.round(iNum * Math.pow(10, iDec)) / Math.pow(10, iDec); }; /** * @param {(number|string)} iSizeInBytes * @return {string} */ Utils.friendlySize = function (iSizeInBytes) { iSizeInBytes = Utils.pInt(iSizeInBytes); if (iSizeInBytes >= 1073741824) { return Utils.roundNumber(iSizeInBytes / 1073741824, 1) + 'GB'; } else if (iSizeInBytes >= 1048576) { return Utils.roundNumber(iSizeInBytes / 1048576, 1) + 'MB'; } else if (iSizeInBytes >= 1024) { return Utils.roundNumber(iSizeInBytes / 1024, 0) + 'KB'; } return iSizeInBytes + 'B'; }; /** * @param {string} sDesc */ Utils.log = function (sDesc) { if (window.console && window.console.log) { window.console.log(sDesc); } }; /** * @param {number} iCode * @param {*=} mMessage = '' * @return {string} */ Utils.getNotification = function (iCode, mMessage) { iCode = Utils.pInt(iCode); if (Enums.Notification.ClientViewError === iCode && mMessage) { return mMessage; } return Utils.isUnd(Globals.oNotificationI18N[iCode]) ? '' : Globals.oNotificationI18N[iCode]; }; Utils.initNotificationLanguage = function () { var oN = Globals.oNotificationI18N || {}; oN[Enums.Notification.InvalidToken] = Utils.i18n('NOTIFICATIONS/INVALID_TOKEN'); oN[Enums.Notification.AuthError] = Utils.i18n('NOTIFICATIONS/AUTH_ERROR'); oN[Enums.Notification.AccessError] = Utils.i18n('NOTIFICATIONS/ACCESS_ERROR'); oN[Enums.Notification.ConnectionError] = Utils.i18n('NOTIFICATIONS/CONNECTION_ERROR'); oN[Enums.Notification.CaptchaError] = Utils.i18n('NOTIFICATIONS/CAPTCHA_ERROR'); oN[Enums.Notification.SocialFacebookLoginAccessDisable] = Utils.i18n('NOTIFICATIONS/SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE'); oN[Enums.Notification.SocialTwitterLoginAccessDisable] = Utils.i18n('NOTIFICATIONS/SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE'); oN[Enums.Notification.SocialGoogleLoginAccessDisable] = Utils.i18n('NOTIFICATIONS/SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE'); oN[Enums.Notification.DomainNotAllowed] = Utils.i18n('NOTIFICATIONS/DOMAIN_NOT_ALLOWED'); oN[Enums.Notification.AccountNotAllowed] = Utils.i18n('NOTIFICATIONS/ACCOUNT_NOT_ALLOWED'); oN[Enums.Notification.AccountTwoFactorAuthRequired] = Utils.i18n('NOTIFICATIONS/ACCOUNT_TWO_FACTOR_AUTH_REQUIRED'); oN[Enums.Notification.AccountTwoFactorAuthError] = Utils.i18n('NOTIFICATIONS/ACCOUNT_TWO_FACTOR_AUTH_ERROR'); oN[Enums.Notification.CouldNotSaveNewPassword] = Utils.i18n('NOTIFICATIONS/COULD_NOT_SAVE_NEW_PASSWORD'); oN[Enums.Notification.CurrentPasswordIncorrect] = Utils.i18n('NOTIFICATIONS/CURRENT_PASSWORD_INCORRECT'); oN[Enums.Notification.NewPasswordShort] = Utils.i18n('NOTIFICATIONS/NEW_PASSWORD_SHORT'); oN[Enums.Notification.NewPasswordWeak] = Utils.i18n('NOTIFICATIONS/NEW_PASSWORD_WEAK'); oN[Enums.Notification.NewPasswordForbidden] = Utils.i18n('NOTIFICATIONS/NEW_PASSWORD_FORBIDDENT'); oN[Enums.Notification.ContactsSyncError] = Utils.i18n('NOTIFICATIONS/CONTACTS_SYNC_ERROR'); oN[Enums.Notification.CantGetMessageList] = Utils.i18n('NOTIFICATIONS/CANT_GET_MESSAGE_LIST'); oN[Enums.Notification.CantGetMessage] = Utils.i18n('NOTIFICATIONS/CANT_GET_MESSAGE'); oN[Enums.Notification.CantDeleteMessage] = Utils.i18n('NOTIFICATIONS/CANT_DELETE_MESSAGE'); oN[Enums.Notification.CantMoveMessage] = Utils.i18n('NOTIFICATIONS/CANT_MOVE_MESSAGE'); oN[Enums.Notification.CantCopyMessage] = Utils.i18n('NOTIFICATIONS/CANT_MOVE_MESSAGE'); oN[Enums.Notification.CantSaveMessage] = Utils.i18n('NOTIFICATIONS/CANT_SAVE_MESSAGE'); oN[Enums.Notification.CantSendMessage] = Utils.i18n('NOTIFICATIONS/CANT_SEND_MESSAGE'); oN[Enums.Notification.InvalidRecipients] = Utils.i18n('NOTIFICATIONS/INVALID_RECIPIENTS'); oN[Enums.Notification.CantCreateFolder] = Utils.i18n('NOTIFICATIONS/CANT_CREATE_FOLDER'); oN[Enums.Notification.CantRenameFolder] = Utils.i18n('NOTIFICATIONS/CANT_RENAME_FOLDER'); oN[Enums.Notification.CantDeleteFolder] = Utils.i18n('NOTIFICATIONS/CANT_DELETE_FOLDER'); oN[Enums.Notification.CantDeleteNonEmptyFolder] = Utils.i18n('NOTIFICATIONS/CANT_DELETE_NON_EMPTY_FOLDER'); oN[Enums.Notification.CantSubscribeFolder] = Utils.i18n('NOTIFICATIONS/CANT_SUBSCRIBE_FOLDER'); oN[Enums.Notification.CantUnsubscribeFolder] = Utils.i18n('NOTIFICATIONS/CANT_UNSUBSCRIBE_FOLDER'); oN[Enums.Notification.CantSaveSettings] = Utils.i18n('NOTIFICATIONS/CANT_SAVE_SETTINGS'); oN[Enums.Notification.CantSavePluginSettings] = Utils.i18n('NOTIFICATIONS/CANT_SAVE_PLUGIN_SETTINGS'); oN[Enums.Notification.DomainAlreadyExists] = Utils.i18n('NOTIFICATIONS/DOMAIN_ALREADY_EXISTS'); oN[Enums.Notification.CantInstallPackage] = Utils.i18n('NOTIFICATIONS/CANT_INSTALL_PACKAGE'); oN[Enums.Notification.CantDeletePackage] = Utils.i18n('NOTIFICATIONS/CANT_DELETE_PACKAGE'); oN[Enums.Notification.InvalidPluginPackage] = Utils.i18n('NOTIFICATIONS/INVALID_PLUGIN_PACKAGE'); oN[Enums.Notification.UnsupportedPluginPackage] = Utils.i18n('NOTIFICATIONS/UNSUPPORTED_PLUGIN_PACKAGE'); oN[Enums.Notification.LicensingServerIsUnavailable] = Utils.i18n('NOTIFICATIONS/LICENSING_SERVER_IS_UNAVAILABLE'); oN[Enums.Notification.LicensingExpired] = Utils.i18n('NOTIFICATIONS/LICENSING_EXPIRED'); oN[Enums.Notification.LicensingBanned] = Utils.i18n('NOTIFICATIONS/LICENSING_BANNED'); oN[Enums.Notification.DemoSendMessageError] = Utils.i18n('NOTIFICATIONS/DEMO_SEND_MESSAGE_ERROR'); oN[Enums.Notification.AccountAlreadyExists] = Utils.i18n('NOTIFICATIONS/ACCOUNT_ALREADY_EXISTS'); oN[Enums.Notification.MailServerError] = Utils.i18n('NOTIFICATIONS/MAIL_SERVER_ERROR'); oN[Enums.Notification.InvalidInputArgument] = Utils.i18n('NOTIFICATIONS/INVALID_INPUT_ARGUMENT'); oN[Enums.Notification.UnknownNotification] = Utils.i18n('NOTIFICATIONS/UNKNOWN_ERROR'); oN[Enums.Notification.UnknownError] = Utils.i18n('NOTIFICATIONS/UNKNOWN_ERROR'); }; /** * @param {*} mCode * @return {string} */ Utils.getUploadErrorDescByCode = function (mCode) { var sResult = ''; switch (Utils.pInt(mCode)) { case Enums.UploadErrorCode.FileIsTooBig: sResult = Utils.i18n('UPLOAD/ERROR_FILE_IS_TOO_BIG'); break; case Enums.UploadErrorCode.FilePartiallyUploaded: sResult = Utils.i18n('UPLOAD/ERROR_FILE_PARTIALLY_UPLOADED'); break; case Enums.UploadErrorCode.FileNoUploaded: sResult = Utils.i18n('UPLOAD/ERROR_NO_FILE_UPLOADED'); break; case Enums.UploadErrorCode.MissingTempFolder: sResult = Utils.i18n('UPLOAD/ERROR_MISSING_TEMP_FOLDER'); break; case Enums.UploadErrorCode.FileOnSaveingError: sResult = Utils.i18n('UPLOAD/ERROR_ON_SAVING_FILE'); break; case Enums.UploadErrorCode.FileType: sResult = Utils.i18n('UPLOAD/ERROR_FILE_TYPE'); break; default: sResult = Utils.i18n('UPLOAD/ERROR_UNKNOWN'); break; } return sResult; }; /** * @param {?} oObject * @param {string} sMethodName * @param {Array=} aParameters * @param {number=} nDelay */ Utils.delegateRun = function (oObject, sMethodName, aParameters, nDelay) { if (oObject && oObject[sMethodName]) { nDelay = Utils.pInt(nDelay); if (0 >= nDelay) { oObject[sMethodName].apply(oObject, Utils.isArray(aParameters) ? aParameters : []); } else { _.delay(function () { oObject[sMethodName].apply(oObject, Utils.isArray(aParameters) ? aParameters : []); }, nDelay); } } }; /** * @param {?} oEvent */ Utils.killCtrlAandS = function (oEvent) { oEvent = oEvent || window.event; if (oEvent && oEvent.ctrlKey && !oEvent.shiftKey && !oEvent.altKey) { var oSender = oEvent.target || oEvent.srcElement, iKey = oEvent.keyCode || oEvent.which ; if (iKey === Enums.EventKeyCode.S) { oEvent.preventDefault(); return; } if (oSender && oSender.tagName && oSender.tagName.match(/INPUT|TEXTAREA/i)) { return; } if (iKey === Enums.EventKeyCode.A) { if (window.getSelection) { window.getSelection().removeAllRanges(); } else if (window.document.selection && window.document.selection.clear) { window.document.selection.clear(); } oEvent.preventDefault(); } } }; /** * @param {(Object|null|undefined)} oContext * @param {Function} fExecute * @param {(Function|boolean|null)=} fCanExecute * @return {Function} */ Utils.createCommand = function (oContext, fExecute, fCanExecute) { var fResult = fExecute ? function () { if (fResult.canExecute && fResult.canExecute()) { fExecute.apply(oContext, Array.prototype.slice.call(arguments)); } return false; } : function () {} ; fResult.enabled = ko.observable(true); fCanExecute = Utils.isUnd(fCanExecute) ? true : fCanExecute; if (Utils.isFunc(fCanExecute)) { fResult.canExecute = ko.computed(function () { return fResult.enabled() && fCanExecute.call(oContext); }); } else { fResult.canExecute = ko.computed(function () { return fResult.enabled() && !!fCanExecute; }); } return fResult; }; /** * @param {Object} oData */ Utils.initDataConstructorBySettings = function (oData) { oData.editorDefaultType = ko.observable(Enums.EditorDefaultType.Html); oData.showImages = ko.observable(false); oData.interfaceAnimation = ko.observable(Enums.InterfaceAnimation.Full); oData.contactsAutosave = ko.observable(false); Globals.sAnimationType = Enums.InterfaceAnimation.Full; oData.capaThemes = ko.observable(false); oData.allowLanguagesOnSettings = ko.observable(true); oData.allowLanguagesOnLogin = ko.observable(true); oData.useLocalProxyForExternalImages = ko.observable(false); oData.desktopNotifications = ko.observable(false); oData.useThreads = ko.observable(true); oData.replySameFolder = ko.observable(true); oData.useCheckboxesInList = ko.observable(true); oData.layout = ko.observable(Enums.Layout.SidePreview); oData.usePreviewPane = ko.computed(function () { return Enums.Layout.NoPreview !== oData.layout(); }); oData.interfaceAnimation.subscribe(function (sValue) { if (Globals.bMobileDevice || sValue === Enums.InterfaceAnimation.None) { $html.removeClass('rl-anim rl-anim-full').addClass('no-rl-anim'); Globals.sAnimationType = Enums.InterfaceAnimation.None; } else { switch (sValue) { case Enums.InterfaceAnimation.Full: $html.removeClass('no-rl-anim').addClass('rl-anim rl-anim-full'); Globals.sAnimationType = sValue; break; case Enums.InterfaceAnimation.Normal: $html.removeClass('no-rl-anim rl-anim-full').addClass('rl-anim'); Globals.sAnimationType = sValue; break; } } }); oData.interfaceAnimation.valueHasMutated(); oData.desktopNotificationsPermisions = ko.computed(function () { oData.desktopNotifications(); var iResult = Enums.DesktopNotifications.NotSupported; if (NotificationClass && NotificationClass.permission) { switch (NotificationClass.permission.toLowerCase()) { case 'granted': iResult = Enums.DesktopNotifications.Allowed; break; case 'denied': iResult = Enums.DesktopNotifications.Denied; break; case 'default': iResult = Enums.DesktopNotifications.NotAllowed; break; } } else if (window.webkitNotifications && window.webkitNotifications.checkPermission) { iResult = window.webkitNotifications.checkPermission(); } return iResult; }); oData.useDesktopNotifications = ko.computed({ 'read': function () { return oData.desktopNotifications() && Enums.DesktopNotifications.Allowed === oData.desktopNotificationsPermisions(); }, 'write': function (bValue) { if (bValue) { var iPermission = oData.desktopNotificationsPermisions(); if (Enums.DesktopNotifications.Allowed === iPermission) { oData.desktopNotifications(true); } else if (Enums.DesktopNotifications.NotAllowed === iPermission) { NotificationClass.requestPermission(function () { oData.desktopNotifications.valueHasMutated(); if (Enums.DesktopNotifications.Allowed === oData.desktopNotificationsPermisions()) { if (oData.desktopNotifications()) { oData.desktopNotifications.valueHasMutated(); } else { oData.desktopNotifications(true); } } else { if (oData.desktopNotifications()) { oData.desktopNotifications(false); } else { oData.desktopNotifications.valueHasMutated(); } } }); } else { oData.desktopNotifications(false); } } else { oData.desktopNotifications(false); } } }); oData.language = ko.observable(''); oData.languages = ko.observableArray([]); oData.mainLanguage = ko.computed({ 'read': oData.language, 'write': function (sValue) { if (sValue !== oData.language()) { if (-1 < Utils.inArray(sValue, oData.languages())) { oData.language(sValue); } else if (0 < oData.languages().length) { oData.language(oData.languages()[0]); } } else { oData.language.valueHasMutated(); } } }); oData.theme = ko.observable(''); oData.themes = ko.observableArray([]); oData.mainTheme = ko.computed({ 'read': oData.theme, 'write': function (sValue) { if (sValue !== oData.theme()) { var aThemes = oData.themes(); if (-1 < Utils.inArray(sValue, aThemes)) { oData.theme(sValue); } else if (0 < aThemes.length) { oData.theme(aThemes[0]); } } else { oData.theme.valueHasMutated(); } } }); oData.capaAdditionalAccounts = ko.observable(false); oData.capaAdditionalIdentities = ko.observable(false); oData.capaGravatar = ko.observable(false); oData.determineUserLanguage = ko.observable(false); oData.determineUserDomain = ko.observable(false); oData.messagesPerPage = ko.observable(Consts.Defaults.MessagesPerPage);//.extend({'throttle': 200}); oData.mainMessagesPerPage = oData.messagesPerPage; oData.mainMessagesPerPage = ko.computed({ 'read': oData.messagesPerPage, 'write': function (iValue) { if (-1 < Utils.inArray(Utils.pInt(iValue), Consts.Defaults.MessagesPerPageArray)) { if (iValue !== oData.messagesPerPage()) { oData.messagesPerPage(iValue); } } else { oData.messagesPerPage.valueHasMutated(); } } }); oData.facebookSupported = ko.observable(false); oData.facebookEnable = ko.observable(false); oData.facebookAppID = ko.observable(''); oData.facebookAppSecret = ko.observable(''); oData.twitterEnable = ko.observable(false); oData.twitterConsumerKey = ko.observable(''); oData.twitterConsumerSecret = ko.observable(''); oData.googleEnable = ko.observable(false); oData.googleClientID = ko.observable(''); oData.googleClientSecret = ko.observable(''); oData.googleApiKey = ko.observable(''); oData.dropboxEnable = ko.observable(false); oData.dropboxApiKey = ko.observable(''); oData.contactsIsAllowed = ko.observable(false); }; /** * @param {{moment:Function}} oObject */ Utils.createMomentDate = function (oObject) { if (Utils.isUnd(oObject.moment)) { oObject.moment = ko.observable(moment()); } return ko.computed(function () { Globals.momentTrigger(); var oMoment = this.moment(); return 1970 === oMoment.year() ? '' : oMoment.fromNow(); }, oObject); }; /** * @param {{moment:Function, momentDate:Function}} oObject */ Utils.createMomentShortDate = function (oObject) { return ko.computed(function () { var sResult = '', oMomentNow = moment(), oMoment = this.moment(), sMomentDate = this.momentDate() ; if (1970 === oMoment.year()) { sResult = ''; } else if (4 >= oMomentNow.diff(oMoment, 'hours')) { sResult = sMomentDate; } else if (oMomentNow.format('L') === oMoment.format('L')) { sResult = Utils.i18n('MESSAGE_LIST/TODAY_AT', { 'TIME': oMoment.format('LT') }); } else if (oMomentNow.clone().subtract('days', 1).format('L') === oMoment.format('L')) { sResult = Utils.i18n('MESSAGE_LIST/YESTERDAY_AT', { 'TIME': oMoment.format('LT') }); } else if (oMomentNow.year() === oMoment.year()) { sResult = oMoment.format('D MMM.'); } else { sResult = oMoment.format('LL'); } return sResult; }, oObject); }; /** * @param {string} sFullNameHash * @return {boolean} */ Utils.isFolderExpanded = function (sFullNameHash) { var aExpandedList = /** @type {Array|null} */ LocalStorage.get(Enums.ClientSideKeyName.ExpandedFolders); return _.isArray(aExpandedList) && -1 !== _.indexOf(aExpandedList, sFullNameHash); }; /** * @param {string} sFullNameHash * @param {boolean} bExpanded */ Utils.setExpandedFolder = function (sFullNameHash, bExpanded) { var aExpandedList = /** @type {Array|null} */ LocalStorage.get(Enums.ClientSideKeyName.ExpandedFolders); if (!_.isArray(aExpandedList)) { aExpandedList = []; } if (bExpanded) { aExpandedList.push(sFullNameHash); aExpandedList = _.uniq(aExpandedList); } else { aExpandedList = _.without(aExpandedList, sFullNameHash); } LocalStorage.set(Enums.ClientSideKeyName.ExpandedFolders, aExpandedList); }; Utils.initLayoutResizer = function (sLeft, sRight, sClientSideKeyName) { var iDisabledWidth = 60, iMinWidth = 155, oLeft = $(sLeft), oRight = $(sRight), mLeftWidth = LocalStorage.get(sClientSideKeyName) || null, fSetWidth = function (iWidth) { if (iWidth) { oLeft.css({ 'width': '' + iWidth + 'px' }); oRight.css({ 'left': '' + iWidth + 'px' }); } }, fDisable = function (bDisable) { if (bDisable) { oLeft.resizable('disable'); fSetWidth(iDisabledWidth); } else { oLeft.resizable('enable'); var iWidth = Utils.pInt(LocalStorage.get(sClientSideKeyName)) || iMinWidth; fSetWidth(iWidth > iMinWidth ? iWidth : iMinWidth); } }, fResizeFunction = function (oEvent, oObject) { if (oObject && oObject.size && oObject.size.width) { LocalStorage.set(sClientSideKeyName, oObject.size.width); oRight.css({ 'left': '' + oObject.size.width + 'px' }); } } ; if (null !== mLeftWidth) { fSetWidth(mLeftWidth > iMinWidth ? mLeftWidth : iMinWidth); } oLeft.resizable({ 'helper': 'ui-resizable-helper', 'minWidth': iMinWidth, 'maxWidth': 350, 'handles': 'e', 'stop': fResizeFunction }); RL.sub('left-panel.off', function () { fDisable(true); }); RL.sub('left-panel.on', function () { fDisable(false); }); }; /** * @param {Object} oMessageTextBody */ Utils.initBlockquoteSwitcher = function (oMessageTextBody) { if (oMessageTextBody) { var $oList = $('blockquote:not(.rl-bq-switcher)', oMessageTextBody).filter(function () { return 0 === $(this).parent().closest('blockquote', oMessageTextBody).length; }); if ($oList && 0 < $oList.length) { $oList.each(function () { var $self = $(this), iH = $self.height(); if (0 === iH || 100 < iH) { $self.addClass('rl-bq-switcher hidden-bq'); $('') .insertBefore($self) .click(function () { $self.toggleClass('hidden-bq'); Utils.windowResize(); }) .after('
') .before('
') ; } }); } } }; /** * @param {Object} oMessageTextBody */ Utils.removeBlockquoteSwitcher = function (oMessageTextBody) { if (oMessageTextBody) { $(oMessageTextBody).find('blockquote.rl-bq-switcher').each(function () { $(this).removeClass('rl-bq-switcher hidden-bq'); }); $(oMessageTextBody).find('.rlBlockquoteSwitcher').each(function () { $(this).remove(); }); } }; /** * @param {Object} oMessageTextBody */ Utils.toggleMessageBlockquote = function (oMessageTextBody) { if (oMessageTextBody) { oMessageTextBody.find('.rlBlockquoteSwitcher').click(); } }; Utils.convertThemeName = function (sTheme) { if ('@custom' === sTheme.substr(-7)) { sTheme = Utils.trim(sTheme.substring(0, sTheme.length - 7)); } return Utils.trim(sTheme.replace(/[^a-zA-Z]+/g, ' ').replace(/([A-Z])/g, ' $1').replace(/[\s]+/g, ' ')); }; /** * @param {string} sName * @return {string} */ Utils.quoteName = function (sName) { return sName.replace(/["]/g, '\\"'); }; /** * @return {number} */ Utils.microtime = function () { return (new Date()).getTime(); }; /** * * @param {string} sLanguage * @param {boolean=} bEng = false * @return {string} */ Utils.convertLangName = function (sLanguage, bEng) { return Utils.i18n('LANGS_NAMES' + (true === bEng ? '_EN' : '') + '/LANG_' + sLanguage.toUpperCase().replace(/[^a-zA-Z0-9]+/, '_'), null, sLanguage); }; /** * @param {number=} iLen * @return {string} */ Utils.fakeMd5 = function(iLen) { var sResult = '', sLine = '0123456789abcdefghijklmnopqrstuvwxyz' ; iLen = Utils.isUnd(iLen) ? 32 : Utils.pInt(iLen); while (sResult.length < iLen) { sResult += sLine.substr(window.Math.round(window.Math.random() * sLine.length), 1); } return sResult; }; /* jshint ignore:start */ /** * @param {string} s * @return {string} */ Utils.md5 = function(s){function L(k,d){return(k<>>(32-d))}function K(G,k){var I,d,F,H,x;F=(G&2147483648);H=(k&2147483648);I=(G&1073741824);d=(k&1073741824);x=(G&1073741823)+(k&1073741823);if(I&d){return(x^2147483648^F^H)}if(I|d){if(x&1073741824){return(x^3221225472^F^H)}else{return(x^1073741824^F^H)}}else{return(x^F^H)}}function r(d,F,k){return(d&F)|((~d)&k)}function q(d,F,k){return(d&k)|(F&(~k))}function p(d,F,k){return(d^F^k)}function n(d,F,k){return(F^(d|(~k)))}function u(G,F,aa,Z,k,H,I){G=K(G,K(K(r(F,aa,Z),k),I));return K(L(G,H),F)}function f(G,F,aa,Z,k,H,I){G=K(G,K(K(q(F,aa,Z),k),I));return K(L(G,H),F)}function D(G,F,aa,Z,k,H,I){G=K(G,K(K(p(F,aa,Z),k),I));return K(L(G,H),F)}function t(G,F,aa,Z,k,H,I){G=K(G,K(K(n(F,aa,Z),k),I));return K(L(G,H),F)}function e(G){var Z;var F=G.length;var x=F+8;var k=(x-(x%64))/64;var I=(k+1)*16;var aa=Array(I-1);var d=0;var H=0;while(H>>29;return aa}function B(x){var k="",F="",G,d;for(d=0;d<=3;d++){G=(x>>>(d*8))&255;F="0"+G.toString(16);k=k+F.substr(F.length-2,2)}return k}function J(k){k=k.replace(/rn/g,"n");var d="";for(var F=0;F127)&&(x<2048)){d+=String.fromCharCode((x>>6)|192);d+=String.fromCharCode((x&63)|128)}else{d+=String.fromCharCode((x>>12)|224);d+=String.fromCharCode(((x>>6)&63)|128);d+=String.fromCharCode((x&63)|128)}}}return d}var C=Array();var P,h,E,v,g,Y,X,W,V;var S=7,Q=12,N=17,M=22;var A=5,z=9,y=14,w=20;var o=4,m=11,l=16,j=23;var U=6,T=10,R=15,O=21;s=J(s);C=e(s);Y=1732584193;X=4023233417;W=2562383102;V=271733878;for(P=0;P/g, '>').replace(/'); }; Utils.draggeblePlace = function () { return $('
 
').appendTo('#rl-hidden'); }; Utils.defautOptionsAfterRender = function (oOption, oItem) { if (oItem && !Utils.isUnd(oItem.disabled) && oOption) { $(oOption) .toggleClass('disabled', oItem.disabled) .prop('disabled', oItem.disabled) ; } }; /** * @param {Object} oViewModel * @param {string} sTemplateID * @param {string} sTitle * @param {Function=} fCallback */ Utils.windowPopupKnockout = function (oViewModel, sTemplateID, sTitle, fCallback) { var oScript = null, oWin = window.open(''), sFunc = '__OpenerApplyBindingsUid' + Utils.fakeMd5() + '__', oTemplate = $('#' + sTemplateID) ; window[sFunc] = function () { if (oWin && oWin.document.body && oTemplate && oTemplate[0]) { var oBody = $(oWin.document.body); $('#rl-content', oBody).html(oTemplate.html()); $('html', oWin.document).addClass('external ' + $('html').attr('class')); Utils.i18nToNode(oBody); kn.applyExternal(oViewModel, $('#rl-content', oBody)[0]); window[sFunc] = null; fCallback(oWin); } }; oWin.document.open(); oWin.document.write('' + '' + '' + '' + '' + '' + '' + Utils.encodeHtml(sTitle) + '' + '
'); oWin.document.close(); oScript = oWin.document.createElement('script'); oScript.type = 'text/javascript'; oScript.innerHTML = 'if(window&&window.opener&&window.opener[\'' + sFunc + '\']){window.opener[\'' + sFunc + '\']();window.opener[\'' + sFunc + '\']=null}'; oWin.document.getElementsByTagName('head')[0].appendChild(oScript); }; Utils.settingsSaveHelperFunction = function (fCallback, koTrigger, oContext, iTimer) { oContext = oContext || null; iTimer = Utils.isUnd(iTimer) ? 1000 : Utils.pInt(iTimer); return function (sType, mData, bCached, sRequestAction, oRequestParameters) { koTrigger.call(oContext, mData && mData['Result'] ? Enums.SaveSettingsStep.TrueResult : Enums.SaveSettingsStep.FalseResult); if (fCallback) { fCallback.call(oContext, sType, mData, bCached, sRequestAction, oRequestParameters); } _.delay(function () { koTrigger.call(oContext, Enums.SaveSettingsStep.Idle); }, iTimer); }; }; Utils.settingsSaveHelperSimpleFunction = function (koTrigger, oContext) { return Utils.settingsSaveHelperFunction(null, koTrigger, oContext, 1000); }; Utils.$div = $('
'); /** * @param {string} sHtml * @return {string} */ Utils.htmlToPlain = function (sHtml) { var iPos = 0, iP1 = 0, iP2 = 0, iP3 = 0, iLimit = 0, sText = '', splitPlainText = function (sText) { var iLen = 100, sPrefix = '', sSubText = '', sResult = sText, iSpacePos = 0, iNewLinePos = 0 ; while (sResult.length > iLen) { sSubText = sResult.substring(0, iLen); iSpacePos = sSubText.lastIndexOf(' '); iNewLinePos = sSubText.lastIndexOf('\n'); if (-1 !== iNewLinePos) { iSpacePos = iNewLinePos; } if (-1 === iSpacePos) { iSpacePos = iLen; } sPrefix += sSubText.substring(0, iSpacePos) + '\n'; sResult = sResult.substring(iSpacePos + 1); } return sPrefix + sResult; }, convertBlockquote = function (sText) { sText = splitPlainText($.trim(sText)); sText = '> ' + sText.replace(/\n/gm, '\n> '); return sText.replace(/(^|\n)([> ]+)/gm, function () { return (arguments && 2 < arguments.length) ? arguments[1] + $.trim(arguments[2].replace(/[\s]/, '')) + ' ' : ''; }); }, convertDivs = function () { if (arguments && 1 < arguments.length) { var sText = $.trim(arguments[1]); if (0 < sText.length) { sText = sText.replace(/]*>([\s\S\r\n]*)<\/div>/gmi, convertDivs); sText = '\n' + $.trim(sText) + '\n'; } return sText; } return ''; }, convertPre = function () { return (arguments && 1 < arguments.length) ? arguments[1].toString().replace(/[\n]/gm, '
') : ''; }, fixAttibuteValue = function () { return (arguments && 1 < arguments.length) ? '' + arguments[1] + arguments[2].replace(//g, '>') : ''; }, convertLinks = function () { return (arguments && 1 < arguments.length) ? $.trim(arguments[1]) : ''; } ; sText = sHtml .replace(/]*>([\s\S\r\n]*)<\/pre>/gmi, convertPre) .replace(/[\s]+/gm, ' ') .replace(/((?:href|data)\s?=\s?)("[^"]+?"|'[^']+?')/gmi, fixAttibuteValue) .replace(/]*>/gmi, '\n') .replace(/<\/h[\d]>/gi, '\n') .replace(/<\/p>/gi, '\n\n') .replace(/<\/li>/gi, '\n') .replace(/<\/td>/gi, '\n') .replace(/<\/tr>/gi, '\n') .replace(/]*>/gmi, '\n_______________________________\n\n') .replace(/]*>([\s\S\r\n]*)<\/div>/gmi, convertDivs) .replace(/]*>/gmi, '\n__bq__start__\n') .replace(/<\/blockquote>/gmi, '\n__bq__end__\n') .replace(/]*>([\s\S\r\n]*?)<\/a>/gmi, convertLinks) .replace(/<\/div>/gi, '\n') .replace(/ /gi, ' ') .replace(/"/gi, '"') .replace(/<[^>]*>/gm, '') ; sText = Utils.$div.html(sText).text(); sText = sText .replace(/\n[ \t]+/gm, '\n') .replace(/[\n]{3,}/gm, '\n\n') .replace(/>/gi, '>') .replace(/</gi, '<') .replace(/&/gi, '&') ; iPos = 0; iLimit = 100; while (0 < iLimit) { iLimit--; iP1 = sText.indexOf('__bq__start__', iPos); if (-1 < iP1) { iP2 = sText.indexOf('__bq__start__', iP1 + 5); iP3 = sText.indexOf('__bq__end__', iP1 + 5); if ((-1 === iP2 || iP3 < iP2) && iP1 < iP3) { sText = sText.substring(0, iP1) + convertBlockquote(sText.substring(iP1 + 13, iP3)) + sText.substring(iP3 + 11); iPos = 0; } else if (-1 < iP2 && iP2 < iP3) { iPos = iP2 - 1; } else { iPos = 0; } } else { break; } } sText = sText .replace(/__bq__start__/gm, '') .replace(/__bq__end__/gm, '') ; return sText; }; /** * @param {string} sPlain * @param {boolean} bLinkify = false * @return {string} */ Utils.plainToHtml = function (sPlain, bLinkify) { sPlain = sPlain.toString().replace(/\r/g, ''); var bIn = false, bDo = true, bStart = true, aNextText = [], sLine = '', iIndex = 0, aText = sPlain.split("\n") ; do { bDo = false; aNextText = []; for (iIndex = 0; iIndex < aText.length; iIndex++) { sLine = aText[iIndex]; bStart = '>' === sLine.substr(0, 1); if (bStart && !bIn) { bDo = true; bIn = true; aNextText.push('~~~blockquote~~~'); aNextText.push(sLine.substr(1)); } else if (!bStart && bIn) { bIn = false; aNextText.push('~~~/blockquote~~~'); aNextText.push(sLine); } else if (bStart && bIn) { aNextText.push(sLine.substr(1)); } else { aNextText.push(sLine); } } if (bIn) { bIn = false; aNextText.push('~~~/blockquote~~~'); } aText = aNextText; } while (bDo); sPlain = aText.join("\n"); sPlain = sPlain .replace(/&/g, '&') .replace(/>/g, '>').replace(/') .replace(/[\s]*~~~\/blockquote~~~/g, '') .replace(/[\-_~]{10,}/g, '
') .replace(/\n/g, '
'); return bLinkify ? Utils.linkify(sPlain) : sPlain; }; window.rainloop_Utils_htmlToPlain = Utils.htmlToPlain; window.rainloop_Utils_plainToHtml = Utils.plainToHtml; /** * @param {string} sHtml * @return {string} */ Utils.linkify = function (sHtml) { if ($.fn && $.fn.linkify) { sHtml = Utils.$div.html(sHtml.replace(/&/ig, 'amp_amp_12345_amp_amp')) .linkify() .find('.linkified').removeClass('linkified').end() .html() .replace(/amp_amp_12345_amp_amp/g, '&') ; } return sHtml; }; Utils.resizeAndCrop = function (sUrl, iValue, fCallback) { var oTempImg = new window.Image(); oTempImg.onload = function() { var aDiff = [0, 0], oCanvas = document.createElement('canvas'), oCtx = oCanvas.getContext('2d') ; oCanvas.width = iValue; oCanvas.height = iValue; if (this.width > this.height) { aDiff = [this.width - this.height, 0]; } else { aDiff = [0, this.height - this.width]; } oCtx.fillStyle = '#fff'; oCtx.fillRect(0, 0, iValue, iValue); oCtx.drawImage(this, aDiff[0] / 2, aDiff[1] / 2, this.width - aDiff[0], this.height - aDiff[1], 0, 0, iValue, iValue); fCallback(oCanvas.toDataURL('image/jpeg')); }; oTempImg.src = sUrl; }; Utils.computedPagenatorHelper = function (koCurrentPage, koPageCount) { return function() { var iPrev = 0, iNext = 0, iLimit = 2, aResult = [], iCurrentPage = koCurrentPage(), iPageCount = koPageCount(), /** * @param {number} iIndex * @param {boolean=} bPush * @param {string=} sCustomName */ fAdd = function (iIndex, bPush, sCustomName) { var oData = { 'current': iIndex === iCurrentPage, 'name': Utils.isUnd(sCustomName) ? iIndex.toString() : sCustomName.toString(), 'custom': Utils.isUnd(sCustomName) ? false : true, 'title': Utils.isUnd(sCustomName) ? '' : iIndex.toString(), 'value': iIndex.toString() }; if (Utils.isUnd(bPush) ? true : !!bPush) { aResult.push(oData); } else { aResult.unshift(oData); } } ; if (1 < iPageCount || (0 < iPageCount && iPageCount < iCurrentPage)) // if (0 < iPageCount && 0 < iCurrentPage) { if (iPageCount < iCurrentPage) { fAdd(iPageCount); iPrev = iPageCount; iNext = iPageCount; } else { if (3 >= iCurrentPage || iPageCount - 2 <= iCurrentPage) { iLimit += 2; } fAdd(iCurrentPage); iPrev = iCurrentPage; iNext = iCurrentPage; } while (0 < iLimit) { iPrev -= 1; iNext += 1; if (0 < iPrev) { fAdd(iPrev, false); iLimit--; } if (iPageCount >= iNext) { fAdd(iNext, true); iLimit--; } else if (0 >= iPrev) { break; } } if (3 === iPrev) { fAdd(2, false); } else if (3 < iPrev) { fAdd(Math.round((iPrev - 1) / 2), false, '...'); } if (iPageCount - 2 === iNext) { fAdd(iPageCount - 1, true); } else if (iPageCount - 2 > iNext) { fAdd(Math.round((iPageCount + iNext) / 2), true, '...'); } // first and last if (1 < iPrev) { fAdd(1, false); } if (iPageCount > iNext) { fAdd(iPageCount, true); } } return aResult; }; }; Utils.selectElement = function (element) { /* jshint onevar: false */ if (window.getSelection) { var sel = window.getSelection(); sel.removeAllRanges(); var range = document.createRange(); range.selectNodeContents(element); sel.addRange(range); } else if (document.selection) { var textRange = document.body.createTextRange(); textRange.moveToElementText(element); textRange.select(); } /* jshint onevar: true */ }; Utils.disableKeyFilter = function () { if (window.key) { key.filter = function () { return RL.data().useKeyboardShortcuts(); }; } }; Utils.restoreKeyFilter = function () { if (window.key) { key.filter = function (event) { if (RL.data().useKeyboardShortcuts()) { var element = event.target || event.srcElement, tagName = element ? element.tagName : '' ; tagName = tagName.toUpperCase(); return !(tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA' || (element && tagName === 'DIV' && 'editorHtmlArea' === element.className && element.contentEditable) ); } return false; }; } }; Utils.detectDropdownVisibility = _.debounce(function () { Globals.dropdownVisibility(!!_.find(Globals.aBootstrapDropdowns, function (oItem) { return oItem.hasClass('open'); })); }, 50); Utils.triggerAutocompleteInputChange = function (bDelay) { var fFunc = function () { $('.checkAutocomplete').trigger('change'); }; if (bDelay) { _.delay(fFunc, 100); } else { fFunc(); } }; module.exports = Utils; }(module)); },{"../External/$doc.js":11,"../External/$window.js":13,"../External/NotificationClass.js":16,"../External/jquery.js":19,"../External/key.js":20,"../External/ko.js":21,"../External/underscore.js":24,"../External/window.js":25,"../Knoin/Knoin.js":26,"../Storages/LocalStorage.js":36,"./Enums.js":5,"./Globals.js":6}],10:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ 'use strict'; module.exports = require('./jquery.js')('
'); },{"./jquery.js":19}],11:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ 'use strict'; module.exports = require('./jquery.js')(window.document); },{"./jquery.js":19}],12:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ 'use strict'; module.exports = require('./jquery.js')('html'); },{"./jquery.js":19}],13:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ 'use strict'; module.exports = require('./jquery.js')(window); },{"./jquery.js":19}],14:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ 'use strict'; module.exports = require('./window.js')['rainloopAppData'] || {}; },{"./window.js":25}],15:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ 'use strict'; module.exports = JSON; },{}],16:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ 'use strict'; var window = require('./window.js') ; module.exports = window.Notification && window.Notification.requestPermission ? window.Notification : null; },{"./window.js":25}],17:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ 'use strict'; module.exports = crossroads; },{}],18:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ 'use strict'; module.exports = hasher; },{}],19:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ 'use strict'; module.exports = $; },{}],20:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ 'use strict'; module.exports = key; },{}],21:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ (function (module) { 'use strict'; var $ = require('./jquery.js'), _ = require('./underscore.js'), window = require('./window.js'), $window = require('./$window.js'), $doc = require('./$doc.js'), Globals = require('../Common/Globals.js'), Utils = require('../Common/Utils.js'), RL = require('../RL.js') ; ko.bindingHandlers.tooltip = { 'init': function (oElement, fValueAccessor) { if (!Globals.bMobileDevice) { var $oEl = $(oElement), sClass = $oEl.data('tooltip-class') || '', sPlacement = $oEl.data('tooltip-placement') || 'top' ; $oEl.tooltip({ 'delay': { 'show': 500, 'hide': 100 }, 'html': true, 'container': 'body', 'placement': sPlacement, 'trigger': 'hover', 'title': function () { return $oEl.is('.disabled') || Globals.dropdownVisibility() ? '' : '' + Utils.i18n(ko.utils.unwrapObservable(fValueAccessor())) + ''; } }).click(function () { $oEl.tooltip('hide'); }); Globals.tooltipTrigger.subscribe(function () { $oEl.tooltip('hide'); }); } } }; ko.bindingHandlers.tooltip2 = { 'init': function (oElement, fValueAccessor) { var $oEl = $(oElement), sClass = $oEl.data('tooltip-class') || '', sPlacement = $oEl.data('tooltip-placement') || 'top' ; $oEl.tooltip({ 'delay': { 'show': 500, 'hide': 100 }, 'html': true, 'container': 'body', 'placement': sPlacement, 'title': function () { return $oEl.is('.disabled') || Globals.dropdownVisibility() ? '' : '' + fValueAccessor()() + ''; } }).click(function () { $oEl.tooltip('hide'); }); Globals.tooltipTrigger.subscribe(function () { $oEl.tooltip('hide'); }); } }; ko.bindingHandlers.tooltip3 = { 'init': function (oElement) { var $oEl = $(oElement); $oEl.tooltip({ 'container': 'body', 'trigger': 'hover manual', 'title': function () { return $oEl.data('tooltip3-data') || ''; } }); $doc.click(function () { $oEl.tooltip('hide'); }); Globals.tooltipTrigger.subscribe(function () { $oEl.tooltip('hide'); }); }, 'update': function (oElement, fValueAccessor) { var sValue = ko.utils.unwrapObservable(fValueAccessor()); if ('' === sValue) { $(oElement).data('tooltip3-data', '').tooltip('hide'); } else { $(oElement).data('tooltip3-data', sValue).tooltip('show'); } } }; ko.bindingHandlers.registrateBootstrapDropdown = { 'init': function (oElement) { Globals.aBootstrapDropdowns.push($(oElement)); } }; ko.bindingHandlers.openDropdownTrigger = { 'update': function (oElement, fValueAccessor) { if (ko.utils.unwrapObservable(fValueAccessor())) { var $el = $(oElement); if (!$el.hasClass('open')) { $el.find('.dropdown-toggle').dropdown('toggle'); Utils.detectDropdownVisibility(); } fValueAccessor()(false); } } }; ko.bindingHandlers.dropdownCloser = { 'init': function (oElement) { $(oElement).closest('.dropdown').on('click', '.e-item', function () { $(oElement).dropdown('toggle'); }); } }; ko.bindingHandlers.popover = { 'init': function (oElement, fValueAccessor) { $(oElement).popover(ko.utils.unwrapObservable(fValueAccessor())); } }; ko.bindingHandlers.csstext = { 'init': function (oElement, fValueAccessor) { if (oElement && oElement.styleSheet && !Utils.isUnd(oElement.styleSheet.cssText)) { oElement.styleSheet.cssText = ko.utils.unwrapObservable(fValueAccessor()); } else { $(oElement).text(ko.utils.unwrapObservable(fValueAccessor())); } }, 'update': function (oElement, fValueAccessor) { if (oElement && oElement.styleSheet && !Utils.isUnd(oElement.styleSheet.cssText)) { oElement.styleSheet.cssText = ko.utils.unwrapObservable(fValueAccessor()); } else { $(oElement).text(ko.utils.unwrapObservable(fValueAccessor())); } } }; ko.bindingHandlers.resizecrop = { 'init': function (oElement) { $(oElement).addClass('resizecrop').resizecrop({ 'width': '100', 'height': '100', 'wrapperCSS': { 'border-radius': '10px' } }); }, 'update': function (oElement, fValueAccessor) { fValueAccessor()(); $(oElement).resizecrop({ 'width': '100', 'height': '100' }); } }; ko.bindingHandlers.onEnter = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { $(oElement).on('keypress', function (oEvent) { if (oEvent && 13 === window.parseInt(oEvent.keyCode, 10)) { $(oElement).trigger('change'); fValueAccessor().call(oViewModel); } }); } }; ko.bindingHandlers.onEsc = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { $(oElement).on('keypress', function (oEvent) { if (oEvent && 27 === window.parseInt(oEvent.keyCode, 10)) { $(oElement).trigger('change'); fValueAccessor().call(oViewModel); } }); } }; ko.bindingHandlers.clickOnTrue = { 'update': function (oElement, fValueAccessor) { if (ko.utils.unwrapObservable(fValueAccessor())) { $(oElement).click(); } } }; ko.bindingHandlers.modal = { 'init': function (oElement, fValueAccessor) { $(oElement).toggleClass('fade', !Globals.bMobileDevice).modal({ 'keyboard': false, 'show': ko.utils.unwrapObservable(fValueAccessor()) }) .on('shown', function () { Utils.windowResize(); }) .find('.close').click(function () { fValueAccessor()(false); }); }, 'update': function (oElement, fValueAccessor) { $(oElement).modal(ko.utils.unwrapObservable(fValueAccessor()) ? 'show' : 'hide'); } }; ko.bindingHandlers.i18nInit = { 'init': function (oElement) { Utils.i18nToNode(oElement); } }; ko.bindingHandlers.i18nUpdate = { 'update': function (oElement, fValueAccessor) { ko.utils.unwrapObservable(fValueAccessor()); Utils.i18nToNode(oElement); } }; ko.bindingHandlers.link = { 'update': function (oElement, fValueAccessor) { $(oElement).attr('href', ko.utils.unwrapObservable(fValueAccessor())); } }; ko.bindingHandlers.title = { 'update': function (oElement, fValueAccessor) { $(oElement).attr('title', ko.utils.unwrapObservable(fValueAccessor())); } }; ko.bindingHandlers.textF = { 'init': function (oElement, fValueAccessor) { $(oElement).text(ko.utils.unwrapObservable(fValueAccessor())); } }; ko.bindingHandlers.initDom = { 'init': function (oElement, fValueAccessor) { fValueAccessor()(oElement); } }; ko.bindingHandlers.initResizeTrigger = { 'init': function (oElement, fValueAccessor) { var aValues = ko.utils.unwrapObservable(fValueAccessor()); $(oElement).css({ 'height': aValues[1], 'min-height': aValues[1] }); }, 'update': function (oElement, fValueAccessor) { var aValues = ko.utils.unwrapObservable(fValueAccessor()), iValue = Utils.pInt(aValues[1]), iSize = 0, iOffset = $(oElement).offset().top ; if (0 < iOffset) { iOffset += Utils.pInt(aValues[2]); iSize = $window.height() - iOffset; if (iValue < iSize) { iValue = iSize; } $(oElement).css({ 'height': iValue, 'min-height': iValue }); } } }; ko.bindingHandlers.appendDom = { 'update': function (oElement, fValueAccessor) { $(oElement).hide().empty().append(ko.utils.unwrapObservable(fValueAccessor())).show(); } }; ko.bindingHandlers.draggable = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor) { if (!Globals.bMobileDevice) { var iTriggerZone = 100, iScrollSpeed = 3, fAllValueFunc = fAllBindingsAccessor(), sDroppableSelector = fAllValueFunc && fAllValueFunc['droppableSelector'] ? fAllValueFunc['droppableSelector'] : '', oConf = { 'distance': 20, 'handle': '.dragHandle', 'cursorAt': {'top': 22, 'left': 3}, 'refreshPositions': true, 'scroll': true } ; if (sDroppableSelector) { oConf['drag'] = function (oEvent) { $(sDroppableSelector).each(function () { var moveUp = null, moveDown = null, $this = $(this), oOffset = $this.offset(), bottomPos = oOffset.top + $this.height() ; window.clearInterval($this.data('timerScroll')); $this.data('timerScroll', false); if (oEvent.pageX >= oOffset.left && oEvent.pageX <= oOffset.left + $this.width()) { if (oEvent.pageY >= bottomPos - iTriggerZone && oEvent.pageY <= bottomPos) { moveUp = function() { $this.scrollTop($this.scrollTop() + iScrollSpeed); Utils.windowResize(); }; $this.data('timerScroll', window.setInterval(moveUp, 10)); moveUp(); } if (oEvent.pageY >= oOffset.top && oEvent.pageY <= oOffset.top + iTriggerZone) { moveDown = function() { $this.scrollTop($this.scrollTop() - iScrollSpeed); Utils.windowResize(); }; $this.data('timerScroll', window.setInterval(moveDown, 10)); moveDown(); } } }); }; oConf['stop'] = function() { $(sDroppableSelector).each(function () { window.clearInterval($(this).data('timerScroll')); $(this).data('timerScroll', false); }); }; } oConf['helper'] = function (oEvent) { return fValueAccessor()(oEvent && oEvent.target ? ko.dataFor(oEvent.target) : null); }; $(oElement).draggable(oConf).on('mousedown', function () { Utils.removeInFocus(); }); } } }; ko.bindingHandlers.droppable = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor) { if (!Globals.bMobileDevice) { var fValueFunc = fValueAccessor(), fAllValueFunc = fAllBindingsAccessor(), fOverCallback = fAllValueFunc && fAllValueFunc['droppableOver'] ? fAllValueFunc['droppableOver'] : null, fOutCallback = fAllValueFunc && fAllValueFunc['droppableOut'] ? fAllValueFunc['droppableOut'] : null, oConf = { 'tolerance': 'pointer', 'hoverClass': 'droppableHover' } ; if (fValueFunc) { oConf['drop'] = function (oEvent, oUi) { fValueFunc(oEvent, oUi); }; if (fOverCallback) { oConf['over'] = function (oEvent, oUi) { fOverCallback(oEvent, oUi); }; } if (fOutCallback) { oConf['out'] = function (oEvent, oUi) { fOutCallback(oEvent, oUi); }; } $(oElement).droppable(oConf); } } } }; ko.bindingHandlers.nano = { 'init': function (oElement) { if (!Globals.bDisableNanoScroll) { $(oElement) .addClass('nano') .nanoScroller({ 'iOSNativeScrolling': false, 'preventPageScrolling': true }) ; } } }; ko.bindingHandlers.saveTrigger = { 'init': function (oElement) { var $oEl = $(oElement); $oEl.data('save-trigger-type', $oEl.is('input[type=text],input[type=email],input[type=password],select,textarea') ? 'input' : 'custom'); if ('custom' === $oEl.data('save-trigger-type')) { $oEl.append( '  ' ).addClass('settings-saved-trigger'); } else { $oEl.addClass('settings-saved-trigger-input'); } }, 'update': function (oElement, fValueAccessor) { var mValue = ko.utils.unwrapObservable(fValueAccessor()), $oEl = $(oElement) ; if ('custom' === $oEl.data('save-trigger-type')) { switch (mValue.toString()) { case '1': $oEl .find('.animated,.error').hide().removeClass('visible') .end() .find('.success').show().addClass('visible') ; break; case '0': $oEl .find('.animated,.success').hide().removeClass('visible') .end() .find('.error').show().addClass('visible') ; break; case '-2': $oEl .find('.error,.success').hide().removeClass('visible') .end() .find('.animated').show().addClass('visible') ; break; default: $oEl .find('.animated').hide() .end() .find('.error,.success').removeClass('visible') ; break; } } else { switch (mValue.toString()) { case '1': $oEl.addClass('success').removeClass('error'); break; case '0': $oEl.addClass('error').removeClass('success'); break; case '-2': // $oEl; break; default: $oEl.removeClass('error success'); break; } } } }; ko.bindingHandlers.emailsTags = { 'init': function(oElement, fValueAccessor) { var $oEl = $(oElement), fValue = fValueAccessor(), fFocusCallback = function (bValue) { if (fValue && fValue.focusTrigger) { fValue.focusTrigger(bValue); } } ; $oEl.inputosaurus({ 'parseOnBlur': true, 'allowDragAndDrop': true, 'focusCallback': fFocusCallback, 'inputDelimiters': [',', ';'], 'autoCompleteSource': function (oData, fResponse) { RL().getAutocomplete(oData.term, function (aData) { fResponse(_.map(aData, function (oEmailItem) { return oEmailItem.toLine(false); })); }); }, 'parseHook': function (aInput) { return _.map(aInput, function (sInputValue) { var sValue = Utils.trim(sInputValue), oEmail = null ; if ('' !== sValue) { oEmail = new EmailModel(); oEmail.mailsoParse(sValue); oEmail.clearDuplicateName(); return [oEmail.toLine(false), oEmail]; } return [sValue, null]; }); }, 'change': _.bind(function (oEvent) { $oEl.data('EmailsTagsValue', oEvent.target.value); fValue(oEvent.target.value); }, this) }); }, 'update': function (oElement, fValueAccessor, fAllBindingsAccessor) { var $oEl = $(oElement), fAllValueFunc = fAllBindingsAccessor(), fEmailsTagsFilter = fAllValueFunc['emailsTagsFilter'] || null, sValue = ko.utils.unwrapObservable(fValueAccessor()) ; if ($oEl.data('EmailsTagsValue') !== sValue) { $oEl.val(sValue); $oEl.data('EmailsTagsValue', sValue); $oEl.inputosaurus('refresh'); } if (fEmailsTagsFilter && ko.utils.unwrapObservable(fEmailsTagsFilter)) { $oEl.inputosaurus('focus'); } } }; ko.bindingHandlers.contactTags = { 'init': function(oElement, fValueAccessor) { var $oEl = $(oElement), fValue = fValueAccessor(), fFocusCallback = function (bValue) { if (fValue && fValue.focusTrigger) { fValue.focusTrigger(bValue); } } ; $oEl.inputosaurus({ 'parseOnBlur': true, 'allowDragAndDrop': false, 'focusCallback': fFocusCallback, 'inputDelimiters': [',', ';'], 'outputDelimiter': ',', 'autoCompleteSource': function (oData, fResponse) { RL().getContactTagsAutocomplete(oData.term, function (aData) { fResponse(_.map(aData, function (oTagItem) { return oTagItem.toLine(false); })); }); }, 'parseHook': function (aInput) { return _.map(aInput, function (sInputValue) { var sValue = Utils.trim(sInputValue), oTag = null ; if ('' !== sValue) { oTag = new ContactTagModel(); oTag.name(sValue); return [oTag.toLine(false), oTag]; } return [sValue, null]; }); }, 'change': _.bind(function (oEvent) { $oEl.data('ContactTagsValue', oEvent.target.value); fValue(oEvent.target.value); }, this) }); }, 'update': function (oElement, fValueAccessor, fAllBindingsAccessor) { var $oEl = $(oElement), fAllValueFunc = fAllBindingsAccessor(), fContactTagsFilter = fAllValueFunc['contactTagsFilter'] || null, sValue = ko.utils.unwrapObservable(fValueAccessor()) ; if ($oEl.data('ContactTagsValue') !== sValue) { $oEl.val(sValue); $oEl.data('ContactTagsValue', sValue); $oEl.inputosaurus('refresh'); } if (fContactTagsFilter && ko.utils.unwrapObservable(fContactTagsFilter)) { $oEl.inputosaurus('focus'); } } }; ko.bindingHandlers.command = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { var jqElement = $(oElement), oCommand = fValueAccessor() ; if (!oCommand || !oCommand.enabled || !oCommand.canExecute) { throw new Error('You are not using command function'); } jqElement.addClass('command'); ko.bindingHandlers[jqElement.is('form') ? 'submit' : 'click'].init.apply(oViewModel, arguments); }, 'update': function (oElement, fValueAccessor) { var bResult = true, jqElement = $(oElement), oCommand = fValueAccessor() ; bResult = oCommand.enabled(); jqElement.toggleClass('command-not-enabled', !bResult); if (bResult) { bResult = oCommand.canExecute(); jqElement.toggleClass('command-can-not-be-execute', !bResult); } jqElement.toggleClass('command-disabled disable disabled', !bResult).toggleClass('no-disabled', !!bResult); if (jqElement.is('input') || jqElement.is('button')) { jqElement.prop('disabled', !bResult); } } }; ko.extenders.trimmer = function (oTarget) { var oResult = ko.computed({ 'read': oTarget, 'write': function (sNewValue) { oTarget(Utils.trim(sNewValue.toString())); }, 'owner': this }); oResult(oTarget()); return oResult; }; ko.extenders.posInterer = function (oTarget, iDefault) { var oResult = ko.computed({ 'read': oTarget, 'write': function (sNewValue) { var iNew = Utils.pInt(sNewValue.toString(), iDefault); if (0 >= iNew) { iNew = iDefault; } if (iNew === oTarget() && '' + iNew !== '' + sNewValue) { oTarget(iNew + 1); } oTarget(iNew); } }); oResult(oTarget()); return oResult; }; ko.extenders.reversible = function (oTarget) { var mValue = oTarget(); oTarget.commit = function () { mValue = oTarget(); }; oTarget.reverse = function () { oTarget(mValue); }; oTarget.commitedValue = function () { return mValue; }; return oTarget; }; ko.extenders.toggleSubscribe = function (oTarget, oOptions) { oTarget.subscribe(oOptions[1], oOptions[0], 'beforeChange'); oTarget.subscribe(oOptions[2], oOptions[0]); return oTarget; }; ko.extenders.falseTimeout = function (oTarget, iOption) { oTarget.iTimeout = 0; oTarget.subscribe(function (bValue) { if (bValue) { window.clearTimeout(oTarget.iTimeout); oTarget.iTimeout = window.setTimeout(function () { oTarget(false); oTarget.iTimeout = 0; }, Utils.pInt(iOption)); } }); return oTarget; }; ko.observable.fn.validateNone = function () { this.hasError = ko.observable(false); return this; }; ko.observable.fn.validateEmail = function () { this.hasError = ko.observable(false); this.subscribe(function (sValue) { sValue = Utils.trim(sValue); this.hasError('' !== sValue && !(/^[^@\s]+@[^@\s]+$/.test(sValue))); }, this); this.valueHasMutated(); return this; }; ko.observable.fn.validateSimpleEmail = function () { this.hasError = ko.observable(false); this.subscribe(function (sValue) { sValue = Utils.trim(sValue); this.hasError('' !== sValue && !(/^.+@.+$/.test(sValue))); }, this); this.valueHasMutated(); return this; }; ko.observable.fn.validateFunc = function (fFunc) { this.hasFuncError = ko.observable(false); if (Utils.isFunc(fFunc)) { this.subscribe(function (sValue) { this.hasFuncError(!fFunc(sValue)); }, this); this.valueHasMutated(); } return this; }; module.exports = ko; }(module)); },{"../Common/Globals.js":6,"../Common/Utils.js":9,"../RL.js":32,"./$doc.js":11,"./$window.js":13,"./jquery.js":19,"./underscore.js":24,"./window.js":25}],22:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ 'use strict'; module.exports = moment; },{}],23:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ 'use strict'; module.exports = ssm; },{}],24:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ 'use strict'; module.exports = window; },{}],25:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ 'use strict'; module.exports = window; },{}],26:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ (function (module) { 'use strict'; var $ = require('../External/jquery.js'), _ = require('../External/underscore.js'), ko = require('../External/ko.js'), hasher = require('../External/hasher.js'), crossroads = require('../External/crossroads.js'), $html = require('../External/$html.js'), Globals = require('../Common/Globals.js'), Enums = require('../Common/Enums.js'), Plugins = require('../Common/Plugins.js'), Utils = require('../Common/Utils.js'), KnoinAbstractViewModel = require('../Knoin/KnoinAbstractViewModel.js') ; /** * @constructor */ function Knoin() { this.sDefaultScreenName = ''; this.oScreens = {}; this.oBoot = null; this.oCurrentScreen = null; } /** * @param {Object} thisObject */ Knoin.constructorEnd = function (thisObject) { if (Utils.isFunc(thisObject['__constructor_end'])) { thisObject['__constructor_end'].call(thisObject); } }; Knoin.prototype.sDefaultScreenName = ''; Knoin.prototype.oScreens = {}; Knoin.prototype.oBoot = null; Knoin.prototype.oCurrentScreen = null; Knoin.prototype.hideLoading = function () { $('#rl-loading').hide(); }; Knoin.prototype.rl = function () { return this.oBoot; }; Knoin.prototype.remote = function () { return this.oRemote; }; /** * @param {Object} thisObject */ Knoin.prototype.constructorEnd = function (thisObject) { if (Utils.isFunc(thisObject['__constructor_end'])) { thisObject['__constructor_end'].call(thisObject); } }; /** * @param {string} sName * @param {Function} ViewModelClass * @param {Function=} AbstractViewModel = KnoinAbstractViewModel */ Knoin.prototype.extendAsViewModel = function (sName, ViewModelClass, AbstractViewModel) { if (ViewModelClass) { if (!AbstractViewModel) { AbstractViewModel = KnoinAbstractViewModel; } ViewModelClass.__name = sName; Plugins.regViewModelHook(sName, ViewModelClass); _.extend(ViewModelClass.prototype, AbstractViewModel.prototype); } }; /** * @param {Function} SettingsViewModelClass * @param {string} sLabelName * @param {string} sTemplate * @param {string} sRoute * @param {boolean=} bDefault */ Knoin.prototype.addSettingsViewModel = function (SettingsViewModelClass, sTemplate, sLabelName, sRoute, bDefault) { SettingsViewModelClass.__rlSettingsData = { 'Label': sLabelName, 'Template': sTemplate, 'Route': sRoute, 'IsDefault': !!bDefault }; Globals.aViewModels['settings'].push(SettingsViewModelClass); }; /** * @param {Function} SettingsViewModelClass */ Knoin.prototype.removeSettingsViewModel = function (SettingsViewModelClass) { Globals.aViewModels['settings-removed'].push(SettingsViewModelClass); }; /** * @param {Function} SettingsViewModelClass */ Knoin.prototype.disableSettingsViewModel = function (SettingsViewModelClass) { Globals.aViewModels['settings-disabled'].push(SettingsViewModelClass); }; Knoin.prototype.routeOff = function () { hasher.changed.active = false; }; Knoin.prototype.routeOn = function () { hasher.changed.active = true; }; /** * @param {string} sScreenName * @return {?Object} */ Knoin.prototype.screen = function (sScreenName) { return ('' !== sScreenName && !Utils.isUnd(this.oScreens[sScreenName])) ? this.oScreens[sScreenName] : null; }; /** * @param {Function} ViewModelClass * @param {Object=} oScreen */ Knoin.prototype.buildViewModel = function (ViewModelClass, oScreen) { if (ViewModelClass && !ViewModelClass.__builded) { var oViewModel = new ViewModelClass(oScreen), sPosition = oViewModel.viewModelPosition(), oViewModelPlace = $('#rl-content #rl-' + sPosition.toLowerCase()), oViewModelDom = null ; ViewModelClass.__builded = true; ViewModelClass.__vm = oViewModel; oViewModel.data = RL.data(); // TODO cjs oViewModel.viewModelName = ViewModelClass.__name; if (oViewModelPlace && 1 === oViewModelPlace.length) { oViewModelDom = $('
').addClass('rl-view-model').addClass('RL-' + oViewModel.viewModelTemplate()).hide(); oViewModelDom.appendTo(oViewModelPlace); oViewModel.viewModelDom = oViewModelDom; ViewModelClass.__dom = oViewModelDom; if ('Popups' === sPosition) { oViewModel.cancelCommand = oViewModel.closeCommand = Utils.createCommand(oViewModel, function () { kn.hideScreenPopup(ViewModelClass); // TODO cjs }); oViewModel.modalVisibility.subscribe(function (bValue) { var self = this; if (bValue) { this.viewModelDom.show(); this.storeAndSetKeyScope(); RL.popupVisibilityNames.push(this.viewModelName); // TODO cjs oViewModel.viewModelDom.css('z-index', 3000 + RL.popupVisibilityNames().length + 10); // TODO cjs Utils.delegateRun(this, 'onFocus', [], 500); } else { Utils.delegateRun(this, 'onHide'); this.restoreKeyScope(); RL.popupVisibilityNames.remove(this.viewModelName); // TODO cjs oViewModel.viewModelDom.css('z-index', 2000); Globals.tooltipTrigger(!Globals.tooltipTrigger()); _.delay(function () { self.viewModelDom.hide(); }, 300); } }, oViewModel); } Plugins.runHook('view-model-pre-build', [ViewModelClass.__name, oViewModel, oViewModelDom]); // TODO cjs ko.applyBindingAccessorsToNode(oViewModelDom[0], { 'i18nInit': true, 'template': function () { return {'name': oViewModel.viewModelTemplate()};} }, oViewModel); Utils.delegateRun(oViewModel, 'onBuild', [oViewModelDom]); if (oViewModel && 'Popups' === sPosition) { oViewModel.registerPopupKeyDown(); } Plugins.runHook('view-model-post-build', [ViewModelClass.__name, oViewModel, oViewModelDom]); // TODO cjs } else { Utils.log('Cannot find view model position: ' + sPosition); } } return ViewModelClass ? ViewModelClass.__vm : null; }; /** * @param {Object} oViewModel * @param {Object} oViewModelDom */ Knoin.prototype.applyExternal = function (oViewModel, oViewModelDom) { if (oViewModel && oViewModelDom) { ko.applyBindings(oViewModel, oViewModelDom); } }; /** * @param {Function} ViewModelClassToHide */ Knoin.prototype.hideScreenPopup = function (ViewModelClassToHide) { if (ViewModelClassToHide && ViewModelClassToHide.__vm && ViewModelClassToHide.__dom) { ViewModelClassToHide.__vm.modalVisibility(false); Plugins.runHook('view-model-on-hide', [ViewModelClassToHide.__name, ViewModelClassToHide.__vm]); // TODO cjs } }; /** * @param {Function} ViewModelClassToShow * @param {Array=} aParameters */ Knoin.prototype.showScreenPopup = function (ViewModelClassToShow, aParameters) { if (ViewModelClassToShow) { this.buildViewModel(ViewModelClassToShow); if (ViewModelClassToShow.__vm && ViewModelClassToShow.__dom) { ViewModelClassToShow.__vm.modalVisibility(true); Utils.delegateRun(ViewModelClassToShow.__vm, 'onShow', aParameters || []); Plugins.runHook('view-model-on-show', [ViewModelClassToShow.__name, ViewModelClassToShow.__vm, aParameters || []]); // TODO cjs } } }; /** * @param {Function} ViewModelClassToShow * @return {boolean} */ Knoin.prototype.isPopupVisible = function (ViewModelClassToShow) { return ViewModelClassToShow && ViewModelClassToShow.__vm ? ViewModelClassToShow.__vm.modalVisibility() : false; }; /** * @param {string} sScreenName * @param {string} sSubPart */ Knoin.prototype.screenOnRoute = function (sScreenName, sSubPart) { var self = this, oScreen = null, oCross = null ; if ('' === Utils.pString(sScreenName)) { sScreenName = this.sDefaultScreenName; } if ('' !== sScreenName) { oScreen = this.screen(sScreenName); if (!oScreen) { oScreen = this.screen(this.sDefaultScreenName); if (oScreen) { sSubPart = sScreenName + '/' + sSubPart; sScreenName = this.sDefaultScreenName; } } if (oScreen && oScreen.__started) { if (!oScreen.__builded) { oScreen.__builded = true; if (Utils.isNonEmptyArray(oScreen.viewModels())) { _.each(oScreen.viewModels(), function (ViewModelClass) { this.buildViewModel(ViewModelClass, oScreen); }, this); } Utils.delegateRun(oScreen, 'onBuild'); } _.defer(function () { // hide screen if (self.oCurrentScreen) { Utils.delegateRun(self.oCurrentScreen, 'onHide'); if (Utils.isNonEmptyArray(self.oCurrentScreen.viewModels())) { _.each(self.oCurrentScreen.viewModels(), function (ViewModelClass) { if (ViewModelClass.__vm && ViewModelClass.__dom && 'Popups' !== ViewModelClass.__vm.viewModelPosition()) { ViewModelClass.__dom.hide(); ViewModelClass.__vm.viewModelVisibility(false); Utils.delegateRun(ViewModelClass.__vm, 'onHide'); } }); } } // -- self.oCurrentScreen = oScreen; // show screen if (self.oCurrentScreen) { Utils.delegateRun(self.oCurrentScreen, 'onShow'); Plugins.runHook('screen-on-show', [self.oCurrentScreen.screenName(), self.oCurrentScreen]); // TODO cjs if (Utils.isNonEmptyArray(self.oCurrentScreen.viewModels())) { _.each(self.oCurrentScreen.viewModels(), function (ViewModelClass) { if (ViewModelClass.__vm && ViewModelClass.__dom && 'Popups' !== ViewModelClass.__vm.viewModelPosition()) { ViewModelClass.__dom.show(); ViewModelClass.__vm.viewModelVisibility(true); Utils.delegateRun(ViewModelClass.__vm, 'onShow'); Utils.delegateRun(ViewModelClass.__vm, 'onFocus', [], 200); Plugins.runHook('view-model-on-show', [ViewModelClass.__name, ViewModelClass.__vm]); // TODO cjs } }, self); } } // -- oCross = oScreen.__cross(); if (oCross) { oCross.parse(sSubPart); } }); } } }; /** * @param {Array} aScreensClasses */ Knoin.prototype.startScreens = function (aScreensClasses) { $('#rl-content').css({ 'visibility': 'hidden' }); _.each(aScreensClasses, function (CScreen) { var oScreen = new CScreen(), sScreenName = oScreen ? oScreen.screenName() : '' ; if (oScreen && '' !== sScreenName) { if ('' === this.sDefaultScreenName) { this.sDefaultScreenName = sScreenName; } this.oScreens[sScreenName] = oScreen; } }, this); _.each(this.oScreens, function (oScreen) { if (oScreen && !oScreen.__started && oScreen.__start) { oScreen.__started = true; oScreen.__start(); Plugins.runHook('screen-pre-start', [oScreen.screenName(), oScreen]); // TODO cjs Utils.delegateRun(oScreen, 'onStart'); Plugins.runHook('screen-post-start', [oScreen.screenName(), oScreen]); // TODO cjs } }, this); var oCross = crossroads.create(); oCross.addRoute(/^([a-zA-Z0-9\-]*)\/?(.*)$/, _.bind(this.screenOnRoute, this)); hasher.initialized.add(oCross.parse, oCross); hasher.changed.add(oCross.parse, oCross); hasher.init(); $('#rl-content').css({ 'visibility': 'visible' }); _.delay(function () { $html.removeClass('rl-started-trigger').addClass('rl-started'); }, 50); }; /** * @param {string} sHash * @param {boolean=} bSilence = false * @param {boolean=} bReplace = false */ Knoin.prototype.setHash = function (sHash, bSilence, bReplace) { sHash = '#' === sHash.substr(0, 1) ? sHash.substr(1) : sHash; sHash = '/' === sHash.substr(0, 1) ? sHash.substr(1) : sHash; bReplace = Utils.isUnd(bReplace) ? false : !!bReplace; if (Utils.isUnd(bSilence) ? false : !!bSilence) { hasher.changed.active = false; hasher[bReplace ? 'replaceHash' : 'setHash'](sHash); hasher.changed.active = true; } else { hasher.changed.active = true; hasher[bReplace ? 'replaceHash' : 'setHash'](sHash); hasher.setHash(sHash); } }; /** * @return {Knoin} */ Knoin.prototype.bootstart = function (RL, Remote) { this.oBoot = RL; this.oRemote = Remote; var window = require('../External/window.js'), $window = require('../External/$window.js'), $html = require('../External/$html.js'), Plugins = require('../Common/Plugins.js'), EmailModel = require('../Models/EmailModel.js') ; $html.addClass(Globals.bMobileDevice ? 'mobile' : 'no-mobile'); $window.keydown(Utils.killCtrlAandS).keyup(Utils.killCtrlAandS); $window.unload(function () { Globals.bUnload = true; }); $html.on('click.dropdown.data-api', function () { Utils.detectDropdownVisibility(); }); // export window['rl'] = window['rl'] || {}; window['rl']['addHook'] = Plugins.addHook; window['rl']['settingsGet'] = Plugins.mainSettingsGet; window['rl']['remoteRequest'] = Plugins.remoteRequest; window['rl']['pluginSettingsGet'] = Plugins.settingsGet; window['rl']['addSettingsViewModel'] = _.bind(this.addSettingsViewModel, this); window['rl']['createCommand'] = Utils.createCommand; window['rl']['EmailModel'] = EmailModel; window['rl']['Enums'] = Enums; window['__RLBOOT'] = function (fCall) { // boot $(function () { if (window['rainloopTEMPLATES'] && window['rainloopTEMPLATES'][0]) { $('#rl-templates').html(window['rainloopTEMPLATES'][0]); _.delay(function () { RL.bootstart(); $html.removeClass('no-js rl-booted-trigger').addClass('rl-booted'); }, 50); } else { fCall(false); } window['__RLBOOT'] = null; }); }; }; module.exports = new Knoin(); }(module)); },{"../Common/Enums.js":5,"../Common/Globals.js":6,"../Common/Plugins.js":8,"../Common/Utils.js":9,"../External/$html.js":12,"../External/$window.js":13,"../External/crossroads.js":17,"../External/hasher.js":18,"../External/jquery.js":19,"../External/ko.js":21,"../External/underscore.js":24,"../External/window.js":25,"../Knoin/KnoinAbstractViewModel.js":28,"../Models/EmailModel.js":30}],27:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ (function (module) { 'use strict'; /** * @constructor */ function KnoinAbstractBoot() { } KnoinAbstractBoot.prototype.bootstart = function () { }; module.exports = KnoinAbstractBoot; }(module)); },{}],28:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ (function (module) { 'use strict'; var ko = require('../External/ko.js'), $window = require('../External/$window.js'), Utils = require('../Common/Utils.js'), Enums = require('../Common/Enums.js') ; /** * @param {string=} sPosition = '' * @param {string=} sTemplate = '' * @constructor */ function KnoinAbstractViewModel(sPosition, sTemplate) { this.bDisabeCloseOnEsc = false; this.sPosition = Utils.pString(sPosition); this.sTemplate = Utils.pString(sTemplate); this.sDefaultKeyScope = Enums.KeyState.None; this.sCurrentKeyScope = this.sDefaultKeyScope; this.viewModelName = ''; this.viewModelVisibility = ko.observable(false); this.modalVisibility = ko.observable(false).extend({'rateLimit': 0}); this.viewModelDom = null; } /** * @type {string} */ KnoinAbstractViewModel.prototype.sPosition = ''; /** * @type {string} */ KnoinAbstractViewModel.prototype.sTemplate = ''; /** * @type {string} */ KnoinAbstractViewModel.prototype.viewModelName = ''; /** * @type {?} */ KnoinAbstractViewModel.prototype.viewModelDom = null; /** * @return {string} */ KnoinAbstractViewModel.prototype.viewModelTemplate = function () { return this.sTemplate; }; /** * @return {string} */ KnoinAbstractViewModel.prototype.viewModelPosition = function () { return this.sPosition; }; KnoinAbstractViewModel.prototype.cancelCommand = KnoinAbstractViewModel.prototype.closeCommand = function () { }; KnoinAbstractViewModel.prototype.storeAndSetKeyScope = function () { this.sCurrentKeyScope = RL.data().keyScope(); // TODO cjs RL.data().keyScope(this.sDefaultKeyScope); // TODO cjs }; KnoinAbstractViewModel.prototype.restoreKeyScope = function () { RL.data().keyScope(this.sCurrentKeyScope); // TODO cjs }; KnoinAbstractViewModel.prototype.registerPopupKeyDown = function () { var self = this; $window.on('keydown', function (oEvent) { if (oEvent && self.modalVisibility && self.modalVisibility()) { if (!this.bDisabeCloseOnEsc && Enums.EventKeyCode.Esc === oEvent.keyCode) { Utils.delegateRun(self, 'cancelCommand'); return false; } else if (Enums.EventKeyCode.Backspace === oEvent.keyCode && !Utils.inFocus()) { return false; } } return true; }); }; module.exports = KnoinAbstractViewModel; }(module)); },{"../Common/Enums.js":5,"../Common/Utils.js":9,"../External/$window.js":13,"../External/ko.js":21}],29:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ (function (module) { 'use strict'; var window = require('../External/window.js'), Globals = require('../Common/Globals.js'), Utils = require('../Common/Utils.js'), LinkBuilder = require('../Common/LinkBuilder.js') ; /** * @constructor */ function AttachmentModel() { this.mimeType = ''; this.fileName = ''; this.estimatedSize = 0; this.friendlySize = ''; this.isInline = false; this.isLinked = false; this.cid = ''; this.cidWithOutTags = ''; this.contentLocation = ''; this.download = ''; this.folder = ''; this.uid = ''; this.mimeIndex = ''; } /** * @static * @param {AjaxJsonAttachment} oJsonAttachment * @return {?AttachmentModel} */ AttachmentModel.newInstanceFromJson = function (oJsonAttachment) { var oAttachmentModel = new AttachmentModel(); return oAttachmentModel.initByJson(oJsonAttachment) ? oAttachmentModel : null; }; AttachmentModel.prototype.mimeType = ''; AttachmentModel.prototype.fileName = ''; AttachmentModel.prototype.estimatedSize = 0; AttachmentModel.prototype.friendlySize = ''; AttachmentModel.prototype.isInline = false; AttachmentModel.prototype.isLinked = false; AttachmentModel.prototype.cid = ''; AttachmentModel.prototype.cidWithOutTags = ''; AttachmentModel.prototype.contentLocation = ''; AttachmentModel.prototype.download = ''; AttachmentModel.prototype.folder = ''; AttachmentModel.prototype.uid = ''; AttachmentModel.prototype.mimeIndex = ''; /** * @param {AjaxJsonAttachment} oJsonAttachment */ AttachmentModel.prototype.initByJson = function (oJsonAttachment) { var bResult = false; if (oJsonAttachment && 'Object/Attachment' === oJsonAttachment['@Object']) { this.mimeType = (oJsonAttachment.MimeType || '').toLowerCase(); this.fileName = oJsonAttachment.FileName; this.estimatedSize = Utils.pInt(oJsonAttachment.EstimatedSize); this.isInline = !!oJsonAttachment.IsInline; this.isLinked = !!oJsonAttachment.IsLinked; this.cid = oJsonAttachment.CID; this.contentLocation = oJsonAttachment.ContentLocation; this.download = oJsonAttachment.Download; this.folder = oJsonAttachment.Folder; this.uid = oJsonAttachment.Uid; this.mimeIndex = oJsonAttachment.MimeIndex; this.friendlySize = Utils.friendlySize(this.estimatedSize); this.cidWithOutTags = this.cid.replace(/^<+/, '').replace(/>+$/, ''); bResult = true; } return bResult; }; /** * @return {boolean} */ AttachmentModel.prototype.isImage = function () { return -1 < Utils.inArray(this.mimeType.toLowerCase(), ['image/png', 'image/jpg', 'image/jpeg', 'image/gif'] ); }; /** * @return {boolean} */ AttachmentModel.prototype.isText = function () { return 'text/' === this.mimeType.substr(0, 5) && -1 === Utils.inArray(this.mimeType, ['text/html']); }; /** * @return {boolean} */ AttachmentModel.prototype.isPdf = function () { return Globals.bAllowPdfPreview && 'application/pdf' === this.mimeType; }; /** * @return {string} */ AttachmentModel.prototype.linkDownload = function () { return LinkBuilder.attachmentDownload(this.download); // TODO cjs }; /** * @return {string} */ AttachmentModel.prototype.linkPreview = function () { return LinkBuilder.attachmentPreview(this.download); // TODO cjs }; /** * @return {string} */ AttachmentModel.prototype.linkPreviewAsPlain = function () { return LinkBuilder.attachmentPreviewAsPlain(this.download); }; /** * @return {string} */ AttachmentModel.prototype.generateTransferDownloadUrl = function () { var sLink = this.linkDownload(); if ('http' !== sLink.substr(0, 4)) { sLink = window.location.protocol + '//' + window.location.host + window.location.pathname + sLink; } return this.mimeType + ':' + this.fileName + ':' + sLink; }; /** * @param {AttachmentModel} oAttachment * @param {*} oEvent * @return {boolean} */ AttachmentModel.prototype.eventDragStart = function (oAttachment, oEvent) { var oLocalEvent = oEvent.originalEvent || oEvent; if (oAttachment && oLocalEvent && oLocalEvent.dataTransfer && oLocalEvent.dataTransfer.setData) { oLocalEvent.dataTransfer.setData('DownloadURL', this.generateTransferDownloadUrl()); } return true; }; AttachmentModel.prototype.iconClass = function () { var aParts = this.mimeType.toLocaleString().split('/'), sClass = 'icon-file' ; if (aParts && aParts[1]) { if ('image' === aParts[0]) { sClass = 'icon-file-image'; } else if ('text' === aParts[0]) { sClass = 'icon-file-text'; } else if ('audio' === aParts[0]) { sClass = 'icon-file-music'; } else if ('video' === aParts[0]) { sClass = 'icon-file-movie'; } else if (-1 < Utils.inArray(aParts[1], ['zip', '7z', 'tar', 'rar', 'gzip', 'bzip', 'bzip2', 'x-zip', 'x-7z', 'x-rar', 'x-tar', 'x-gzip', 'x-bzip', 'x-bzip2', 'x-zip-compressed', 'x-7z-compressed', 'x-rar-compressed'])) { sClass = 'icon-file-zip'; } // else if (-1 < Utils.inArray(aParts[1], // ['pdf', 'x-pdf'])) // { // sClass = 'icon-file-pdf'; // } // else if (-1 < Utils.inArray(aParts[1], [ // 'exe', 'x-exe', 'x-winexe', 'bat' // ])) // { // sClass = 'icon-console'; // } else if (-1 < Utils.inArray(aParts[1], [ 'rtf', 'msword', 'vnd.msword', 'vnd.openxmlformats-officedocument.wordprocessingml.document', 'vnd.openxmlformats-officedocument.wordprocessingml.template', 'vnd.ms-word.document.macroEnabled.12', 'vnd.ms-word.template.macroEnabled.12' ])) { sClass = 'icon-file-text'; } else if (-1 < Utils.inArray(aParts[1], [ 'excel', 'ms-excel', 'vnd.ms-excel', 'vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'vnd.openxmlformats-officedocument.spreadsheetml.template', 'vnd.ms-excel.sheet.macroEnabled.12', 'vnd.ms-excel.template.macroEnabled.12', 'vnd.ms-excel.addin.macroEnabled.12', 'vnd.ms-excel.sheet.binary.macroEnabled.12' ])) { sClass = 'icon-file-excel'; } else if (-1 < Utils.inArray(aParts[1], [ 'powerpoint', 'ms-powerpoint', 'vnd.ms-powerpoint', 'vnd.openxmlformats-officedocument.presentationml.presentation', 'vnd.openxmlformats-officedocument.presentationml.template', 'vnd.openxmlformats-officedocument.presentationml.slideshow', 'vnd.ms-powerpoint.addin.macroEnabled.12', 'vnd.ms-powerpoint.presentation.macroEnabled.12', 'vnd.ms-powerpoint.template.macroEnabled.12', 'vnd.ms-powerpoint.slideshow.macroEnabled.12' ])) { sClass = 'icon-file-chart-graph'; } } return sClass; }; module.exports = AttachmentModel; }(module)); },{"../Common/Globals.js":6,"../Common/LinkBuilder.js":7,"../Common/Utils.js":9,"../External/window.js":25}],30:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ (function (module) { 'use strict'; var Enums = require('../Common/Enums.js'), Utils = require('../Common/Utils.js') ; /** * @param {string=} sEmail * @param {string=} sName * * @constructor */ function EmailModel(sEmail, sName) { this.email = sEmail || ''; this.name = sName || ''; this.privateType = null; this.clearDuplicateName(); } /** * @static * @param {AjaxJsonEmail} oJsonEmail * @return {?EmailModel} */ EmailModel.newInstanceFromJson = function (oJsonEmail) { var oEmailModel = new EmailModel(); return oEmailModel.initByJson(oJsonEmail) ? oEmailModel : null; }; /** * @type {string} */ EmailModel.prototype.name = ''; /** * @type {string} */ EmailModel.prototype.email = ''; /** * @type {(number|null)} */ EmailModel.prototype.privateType = null; EmailModel.prototype.clear = function () { this.email = ''; this.name = ''; this.privateType = null; }; /** * @returns {boolean} */ EmailModel.prototype.validate = function () { return '' !== this.name || '' !== this.email; }; /** * @param {boolean} bWithoutName = false * @return {string} */ EmailModel.prototype.hash = function (bWithoutName) { return '#' + (bWithoutName ? '' : this.name) + '#' + this.email + '#'; }; EmailModel.prototype.clearDuplicateName = function () { if (this.name === this.email) { this.name = ''; } }; /** * @return {number} */ EmailModel.prototype.type = function () { if (null === this.privateType) { if (this.email && '@facebook.com' === this.email.substr(-13)) { this.privateType = Enums.EmailType.Facebook; } if (null === this.privateType) { this.privateType = Enums.EmailType.Default; } } return this.privateType; }; /** * @param {string} sQuery * @return {boolean} */ EmailModel.prototype.search = function (sQuery) { return -1 < (this.name + ' ' + this.email).toLowerCase().indexOf(sQuery.toLowerCase()); }; /** * @param {string} sString */ EmailModel.prototype.parse = function (sString) { this.clear(); sString = Utils.trim(sString); var mRegex = /(?:"([^"]+)")? ?,]+)>?,? ?/g, mMatch = mRegex.exec(sString) ; if (mMatch) { this.name = mMatch[1] || ''; this.email = mMatch[2] || ''; this.clearDuplicateName(); } else if ((/^[^@]+@[^@]+$/).test(sString)) { this.name = ''; this.email = sString; } }; /** * @param {AjaxJsonEmail} oJsonEmail * @return {boolean} */ EmailModel.prototype.initByJson = function (oJsonEmail) { var bResult = false; if (oJsonEmail && 'Object/Email' === oJsonEmail['@Object']) { this.name = Utils.trim(oJsonEmail.Name); this.email = Utils.trim(oJsonEmail.Email); bResult = '' !== this.email; this.clearDuplicateName(); } return bResult; }; /** * @param {boolean} bFriendlyView * @param {boolean=} bWrapWithLink = false * @param {boolean=} bEncodeHtml = false * @return {string} */ EmailModel.prototype.toLine = function (bFriendlyView, bWrapWithLink, bEncodeHtml) { var sResult = ''; if ('' !== this.email) { bWrapWithLink = Utils.isUnd(bWrapWithLink) ? false : !!bWrapWithLink; bEncodeHtml = Utils.isUnd(bEncodeHtml) ? false : !!bEncodeHtml; if (bFriendlyView && '' !== this.name) { sResult = bWrapWithLink ? '
') + '" target="_blank" tabindex="-1">' + Utils.encodeHtml(this.name) + '' : (bEncodeHtml ? Utils.encodeHtml(this.name) : this.name); } else { sResult = this.email; if ('' !== this.name) { if (bWrapWithLink) { sResult = Utils.encodeHtml('"' + this.name + '" <') + '') + '" target="_blank" tabindex="-1">' + Utils.encodeHtml(sResult) + '' + Utils.encodeHtml('>'); } else { sResult = '"' + this.name + '" <' + sResult + '>'; if (bEncodeHtml) { sResult = Utils.encodeHtml(sResult); } } } else if (bWrapWithLink) { sResult = '' + Utils.encodeHtml(this.email) + ''; } } } return sResult; }; /** * @param {string} $sEmailAddress * @return {boolean} */ EmailModel.prototype.mailsoParse = function ($sEmailAddress) { $sEmailAddress = Utils.trim($sEmailAddress); if ('' === $sEmailAddress) { return false; } var substr = function (str, start, len) { str += ''; var end = str.length; if (start < 0) { start += end; } end = typeof len === 'undefined' ? end : (len < 0 ? len + end : len + start); return start >= str.length || start < 0 || start > end ? false : str.slice(start, end); }, substr_replace = function (str, replace, start, length) { if (start < 0) { start = start + str.length; } length = length !== undefined ? length : str.length; if (length < 0) { length = length + str.length - start; } return str.slice(0, start) + replace.substr(0, length) + replace.slice(length) + str.slice(start + length); }, $sName = '', $sEmail = '', $sComment = '', $bInName = false, $bInAddress = false, $bInComment = false, $aRegs = null, $iStartIndex = 0, $iEndIndex = 0, $iCurrentIndex = 0 ; while ($iCurrentIndex < $sEmailAddress.length) { switch ($sEmailAddress.substr($iCurrentIndex, 1)) { case '"': if ((!$bInName) && (!$bInAddress) && (!$bInComment)) { $bInName = true; $iStartIndex = $iCurrentIndex; } else if ((!$bInAddress) && (!$bInComment)) { $iEndIndex = $iCurrentIndex; $sName = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1); $sEmailAddress = substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1); $iEndIndex = 0; $iCurrentIndex = 0; $iStartIndex = 0; $bInName = false; } break; case '<': if ((!$bInName) && (!$bInAddress) && (!$bInComment)) { if ($iCurrentIndex > 0 && $sName.length === 0) { $sName = substr($sEmailAddress, 0, $iCurrentIndex); } $bInAddress = true; $iStartIndex = $iCurrentIndex; } break; case '>': if ($bInAddress) { $iEndIndex = $iCurrentIndex; $sEmail = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1); $sEmailAddress = substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1); $iEndIndex = 0; $iCurrentIndex = 0; $iStartIndex = 0; $bInAddress = false; } break; case '(': if ((!$bInName) && (!$bInAddress) && (!$bInComment)) { $bInComment = true; $iStartIndex = $iCurrentIndex; } break; case ')': if ($bInComment) { $iEndIndex = $iCurrentIndex; $sComment = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1); $sEmailAddress = substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1); $iEndIndex = 0; $iCurrentIndex = 0; $iStartIndex = 0; $bInComment = false; } break; case '\\': $iCurrentIndex++; break; } $iCurrentIndex++; } if ($sEmail.length === 0) { $aRegs = $sEmailAddress.match(/[^@\s]+@\S+/i); if ($aRegs && $aRegs[0]) { $sEmail = $aRegs[0]; } else { $sName = $sEmailAddress; } } if ($sEmail.length > 0 && $sName.length === 0 && $sComment.length === 0) { $sName = $sEmailAddress.replace($sEmail, ''); } $sEmail = Utils.trim($sEmail).replace(/^[<]+/, '').replace(/[>]+$/, ''); $sName = Utils.trim($sName).replace(/^["']+/, '').replace(/["']+$/, ''); $sComment = Utils.trim($sComment).replace(/^[(]+/, '').replace(/[)]+$/, ''); // Remove backslash $sName = $sName.replace(/\\\\(.)/, '$1'); $sComment = $sComment.replace(/\\\\(.)/, '$1'); this.name = $sName; this.email = $sEmail; this.clearDuplicateName(); return true; }; /** * @return {string} */ EmailModel.prototype.inputoTagLine = function () { return 0 < this.name.length ? this.name + ' (' + this.email + ')' : this.email; }; module.exports = EmailModel; }(module)); },{"../Common/Enums.js":5,"../Common/Utils.js":9}],31:[function(require,module,exports){ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ (function (module) { 'use strict'; var window = require('../External/window.js'), $ = require('../External/jquery.js'), _ = require('../External/underscore.js'), ko = require('../External/ko.js'), moment = require('../External/moment.js'), $window = require('../External/$window.js'), $div = require('../External/$div.js'), Enums = require('../Common/Enums.js'), Utils = require('../Common/Utils.js'), LinkBuilder = require('../Common/LinkBuilder.js'), EmailModel = require('./EmailModel.js'), AttachmentModel = require('./AttachmentModel.js') ; /** * @constructor */ function MessageModel() { this.folderFullNameRaw = ''; this.uid = ''; this.hash = ''; this.requestHash = ''; this.subject = ko.observable(''); this.subjectPrefix = ko.observable(''); this.subjectSuffix = ko.observable(''); this.size = ko.observable(0); this.dateTimeStampInUTC = ko.observable(0); this.priority = ko.observable(Enums.MessagePriority.Normal); this.proxy = false; this.fromEmailString = ko.observable(''); this.fromClearEmailString = ko.observable(''); this.toEmailsString = ko.observable(''); this.toClearEmailsString = ko.observable(''); this.senderEmailsString = ko.observable(''); this.senderClearEmailsString = ko.observable(''); this.emails = []; this.from = []; this.to = []; this.cc = []; this.bcc = []; this.replyTo = []; this.deliveredTo = []; this.newForAnimation = ko.observable(false); this.deleted = ko.observable(false); this.unseen = ko.observable(false); this.flagged = ko.observable(false); this.answered = ko.observable(false); this.forwarded = ko.observable(false); this.isReadReceipt = ko.observable(false); this.focused = ko.observable(false); this.selected = ko.observable(false); this.checked = ko.observable(false); this.hasAttachments = ko.observable(false); this.attachmentsMainType = ko.observable(''); this.moment = ko.observable(moment(moment.unix(0))); this.attachmentIconClass = ko.computed(function () { var sClass = ''; if (this.hasAttachments()) { sClass = 'icon-attachment'; switch (this.attachmentsMainType()) { case 'image': sClass = 'icon-image'; break; case 'archive': sClass = 'icon-file-zip'; break; case 'doc': sClass = 'icon-file-text'; break; // case 'pdf': // sClass = 'icon-file-pdf'; // break; } } return sClass; }, this); this.fullFormatDateValue = ko.computed(function () { return MessageModel.calculateFullFromatDateValue(this.dateTimeStampInUTC()); }, this); this.momentDate = Utils.createMomentDate(this); this.momentShortDate = Utils.createMomentShortDate(this); this.dateTimeStampInUTC.subscribe(function (iValue) { var iNow = moment().unix(); this.moment(moment.unix(iNow < iValue ? iNow : iValue)); }, this); this.body = null; this.plainRaw = ''; this.isHtml = ko.observable(false); this.hasImages = ko.observable(false); this.attachments = ko.observableArray([]); this.isPgpSigned = ko.observable(false); this.isPgpEncrypted = ko.observable(false); this.pgpSignedVerifyStatus = ko.observable(Enums.SignedVerifyStatus.None); this.pgpSignedVerifyUser = ko.observable(''); this.priority = ko.observable(Enums.MessagePriority.Normal); this.readReceipt = ko.observable(''); this.aDraftInfo = []; this.sMessageId = ''; this.sInReplyTo = ''; this.sReferences = ''; this.parentUid = ko.observable(0); this.threads = ko.observableArray([]); this.threadsLen = ko.observable(0); this.hasUnseenSubMessage = ko.observable(false); this.hasFlaggedSubMessage = ko.observable(false); this.lastInCollapsedThread = ko.observable(false); this.lastInCollapsedThreadLoading = ko.observable(false); this.threadsLenResult = ko.computed(function () { var iCount = this.threadsLen(); return 0 === this.parentUid() && 0 < iCount ? iCount + 1 : ''; }, this); } /** * @static * @param {AjaxJsonMessage} oJsonMessage * @return {?MessageModel} */ MessageModel.newInstanceFromJson = function (oJsonMessage) { var oMessageModel = new MessageModel(); return oMessageModel.initByJson(oJsonMessage) ? oMessageModel : null; }; /** * @static * @param {number} iTimeStampInUTC * @return {string} */ MessageModel.calculateFullFromatDateValue = function (iTimeStampInUTC) { return 0 < iTimeStampInUTC ? moment.unix(iTimeStampInUTC).format('LLL') : ''; }; /** * @static * @param {Array} aEmail * @param {boolean=} bFriendlyView * @param {boolean=} bWrapWithLink = false * @return {string} */ MessageModel.emailsToLine = function (aEmail, bFriendlyView, bWrapWithLink) { var aResult = [], iIndex = 0, iLen = 0 ; if (Utils.isNonEmptyArray(aEmail)) { for (iIndex = 0, iLen = aEmail.length; iIndex < iLen; iIndex++) { aResult.push(aEmail[iIndex].toLine(bFriendlyView, bWrapWithLink)); } } return aResult.join(', '); }; /** * @static * @param {Array} aEmail * @return {string} */ MessageModel.emailsToLineClear = function (aEmail) { var aResult = [], iIndex = 0, iLen = 0 ; if (Utils.isNonEmptyArray(aEmail)) { for (iIndex = 0, iLen = aEmail.length; iIndex < iLen; iIndex++) { if (aEmail[iIndex] && aEmail[iIndex].email && '' !== aEmail[iIndex].name) { aResult.push(aEmail[iIndex].email); } } } return aResult.join(', '); }; /** * @static * @param {?Array} aJsonEmails * @return {Array.} */ MessageModel.initEmailsFromJson = function (aJsonEmails) { var iIndex = 0, iLen = 0, oEmailModel = null, aResult = [] ; if (Utils.isNonEmptyArray(aJsonEmails)) { for (iIndex = 0, iLen = aJsonEmails.length; iIndex < iLen; iIndex++) { oEmailModel = EmailModel.newInstanceFromJson(aJsonEmails[iIndex]); if (oEmailModel) { aResult.push(oEmailModel); } } } return aResult; }; /** * @static * @param {Array.} aMessageEmails * @param {Object} oLocalUnic * @param {Array} aLocalEmails */ MessageModel.replyHelper = function (aMessageEmails, oLocalUnic, aLocalEmails) { if (aMessageEmails && 0 < aMessageEmails.length) { var iIndex = 0, iLen = aMessageEmails.length ; for (; iIndex < iLen; iIndex++) { if (Utils.isUnd(oLocalUnic[aMessageEmails[iIndex].email])) { oLocalUnic[aMessageEmails[iIndex].email] = true; aLocalEmails.push(aMessageEmails[iIndex]); } } } }; MessageModel.prototype.clear = function () { this.folderFullNameRaw = ''; this.uid = ''; this.hash = ''; this.requestHash = ''; this.subject(''); this.subjectPrefix(''); this.subjectSuffix(''); this.size(0); this.dateTimeStampInUTC(0); this.priority(Enums.MessagePriority.Normal); this.proxy = false; this.fromEmailString(''); this.fromClearEmailString(''); this.toEmailsString(''); this.toClearEmailsString(''); this.senderEmailsString(''); this.senderClearEmailsString(''); this.emails = []; this.from = []; this.to = []; this.cc = []; this.bcc = []; this.replyTo = []; this.deliveredTo = []; this.newForAnimation(false); this.deleted(false); this.unseen(false); this.flagged(false); this.answered(false); this.forwarded(false); this.isReadReceipt(false); this.selected(false); this.checked(false); this.hasAttachments(false); this.attachmentsMainType(''); this.body = null; this.isHtml(false); this.hasImages(false); this.attachments([]); this.isPgpSigned(false); this.isPgpEncrypted(false); this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.None); this.pgpSignedVerifyUser(''); this.priority(Enums.MessagePriority.Normal); this.readReceipt(''); this.aDraftInfo = []; this.sMessageId = ''; this.sInReplyTo = ''; this.sReferences = ''; this.parentUid(0); this.threads([]); this.threadsLen(0); this.hasUnseenSubMessage(false); this.hasFlaggedSubMessage(false); this.lastInCollapsedThread(false); this.lastInCollapsedThreadLoading(false); }; MessageModel.prototype.computeSenderEmail = function () { var sSent = RL.data().sentFolder(), sDraft = RL.data().draftFolder() ; this.senderEmailsString(this.folderFullNameRaw === sSent || this.folderFullNameRaw === sDraft ? this.toEmailsString() : this.fromEmailString()); this.senderClearEmailsString(this.folderFullNameRaw === sSent || this.folderFullNameRaw === sDraft ? this.toClearEmailsString() : this.fromClearEmailString()); }; /** * @param {AjaxJsonMessage} oJsonMessage * @return {boolean} */ MessageModel.prototype.initByJson = function (oJsonMessage) { var bResult = false; if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object']) { this.folderFullNameRaw = oJsonMessage.Folder; this.uid = oJsonMessage.Uid; this.hash = oJsonMessage.Hash; this.requestHash = oJsonMessage.RequestHash; this.proxy = !!oJsonMessage.ExternalProxy; this.size(Utils.pInt(oJsonMessage.Size)); this.from = MessageModel.initEmailsFromJson(oJsonMessage.From); this.to = MessageModel.initEmailsFromJson(oJsonMessage.To); this.cc = MessageModel.initEmailsFromJson(oJsonMessage.Cc); this.bcc = MessageModel.initEmailsFromJson(oJsonMessage.Bcc); this.replyTo = MessageModel.initEmailsFromJson(oJsonMessage.ReplyTo); this.deliveredTo = MessageModel.initEmailsFromJson(oJsonMessage.DeliveredTo); this.subject(oJsonMessage.Subject); if (Utils.isArray(oJsonMessage.SubjectParts)) { this.subjectPrefix(oJsonMessage.SubjectParts[0]); this.subjectSuffix(oJsonMessage.SubjectParts[1]); } else { this.subjectPrefix(''); this.subjectSuffix(this.subject()); } this.dateTimeStampInUTC(Utils.pInt(oJsonMessage.DateTimeStampInUTC)); this.hasAttachments(!!oJsonMessage.HasAttachments); this.attachmentsMainType(oJsonMessage.AttachmentsMainType); this.fromEmailString(MessageModel.emailsToLine(this.from, true)); this.fromClearEmailString(MessageModel.emailsToLineClear(this.from)); this.toEmailsString(MessageModel.emailsToLine(this.to, true)); this.toClearEmailsString(MessageModel.emailsToLineClear(this.to)); this.parentUid(Utils.pInt(oJsonMessage.ParentThread)); this.threads(Utils.isArray(oJsonMessage.Threads) ? oJsonMessage.Threads : []); this.threadsLen(Utils.pInt(oJsonMessage.ThreadsLen)); this.initFlagsByJson(oJsonMessage); this.computeSenderEmail(); bResult = true; } return bResult; }; /** * @param {AjaxJsonMessage} oJsonMessage * @return {boolean} */ MessageModel.prototype.initUpdateByMessageJson = function (oJsonMessage) { var bResult = false, iPriority = Enums.MessagePriority.Normal ; if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object']) { iPriority = Utils.pInt(oJsonMessage.Priority); this.priority(-1 < Utils.inArray(iPriority, [Enums.MessagePriority.High, Enums.MessagePriority.Low]) ? iPriority : Enums.MessagePriority.Normal); this.aDraftInfo = oJsonMessage.DraftInfo; this.sMessageId = oJsonMessage.MessageId; this.sInReplyTo = oJsonMessage.InReplyTo; this.sReferences = oJsonMessage.References; this.proxy = !!oJsonMessage.ExternalProxy; if (RL.data().capaOpenPGP()) // TODO cjs { this.isPgpSigned(!!oJsonMessage.PgpSigned); this.isPgpEncrypted(!!oJsonMessage.PgpEncrypted); } this.hasAttachments(!!oJsonMessage.HasAttachments); this.attachmentsMainType(oJsonMessage.AttachmentsMainType); this.foundedCIDs = Utils.isArray(oJsonMessage.FoundedCIDs) ? oJsonMessage.FoundedCIDs : []; this.attachments(this.initAttachmentsFromJson(oJsonMessage.Attachments)); this.readReceipt(oJsonMessage.ReadReceipt || ''); this.computeSenderEmail(); bResult = true; } return bResult; }; /** * @param {(AjaxJsonAttachment|null)} oJsonAttachments * @return {Array} */ MessageModel.prototype.initAttachmentsFromJson = function (oJsonAttachments) { var iIndex = 0, iLen = 0, oAttachmentModel = null, aResult = [] ; if (oJsonAttachments && 'Collection/AttachmentCollection' === oJsonAttachments['@Object'] && Utils.isNonEmptyArray(oJsonAttachments['@Collection'])) { for (iIndex = 0, iLen = oJsonAttachments['@Collection'].length; iIndex < iLen; iIndex++) { oAttachmentModel = AttachmentModel.newInstanceFromJson(oJsonAttachments['@Collection'][iIndex]); if (oAttachmentModel) { if ('' !== oAttachmentModel.cidWithOutTags && 0 < this.foundedCIDs.length && 0 <= Utils.inArray(oAttachmentModel.cidWithOutTags, this.foundedCIDs)) { oAttachmentModel.isLinked = true; } aResult.push(oAttachmentModel); } } } return aResult; }; /** * @param {AjaxJsonMessage} oJsonMessage * @return {boolean} */ MessageModel.prototype.initFlagsByJson = function (oJsonMessage) { var bResult = false; if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object']) { this.unseen(!oJsonMessage.IsSeen); this.flagged(!!oJsonMessage.IsFlagged); this.answered(!!oJsonMessage.IsAnswered); this.forwarded(!!oJsonMessage.IsForwarded); this.isReadReceipt(!!oJsonMessage.IsReadReceipt); bResult = true; } return bResult; }; /** * @param {boolean} bFriendlyView * @param {boolean=} bWrapWithLink = false * @return {string} */ MessageModel.prototype.fromToLine = function (bFriendlyView, bWrapWithLink) { return MessageModel.emailsToLine(this.from, bFriendlyView, bWrapWithLink); }; /** * @param {boolean} bFriendlyView * @param {boolean=} bWrapWithLink = false * @return {string} */ MessageModel.prototype.toToLine = function (bFriendlyView, bWrapWithLink) { return MessageModel.emailsToLine(this.to, bFriendlyView, bWrapWithLink); }; /** * @param {boolean} bFriendlyView * @param {boolean=} bWrapWithLink = false * @return {string} */ MessageModel.prototype.ccToLine = function (bFriendlyView, bWrapWithLink) { return MessageModel.emailsToLine(this.cc, bFriendlyView, bWrapWithLink); }; /** * @param {boolean} bFriendlyView * @param {boolean=} bWrapWithLink = false * @return {string} */ MessageModel.prototype.bccToLine = function (bFriendlyView, bWrapWithLink) { return MessageModel.emailsToLine(this.bcc, bFriendlyView, bWrapWithLink); }; /** * @return string */ MessageModel.prototype.lineAsCcc = function () { var aResult = []; if (this.deleted()) { aResult.push('deleted'); } if (this.selected()) { aResult.push('selected'); } if (this.checked()) { aResult.push('checked'); } if (this.flagged()) { aResult.push('flagged'); } if (this.unseen()) { aResult.push('unseen'); } if (this.answered()) { aResult.push('answered'); } if (this.forwarded()) { aResult.push('forwarded'); } if (this.focused()) { aResult.push('focused'); } if (this.hasAttachments()) { aResult.push('withAttachments'); switch (this.attachmentsMainType()) { case 'image': aResult.push('imageOnlyAttachments'); break; case 'archive': aResult.push('archiveOnlyAttachments'); break; } } if (this.newForAnimation()) { aResult.push('new'); } if ('' === this.subject()) { aResult.push('emptySubject'); } if (0 < this.parentUid()) { aResult.push('hasParentMessage'); } if (0 < this.threadsLen() && 0 === this.parentUid()) { aResult.push('hasChildrenMessage'); } if (this.hasUnseenSubMessage()) { aResult.push('hasUnseenSubMessage'); } if (this.hasFlaggedSubMessage()) { aResult.push('hasFlaggedSubMessage'); } return aResult.join(' '); }; /** * @return {boolean} */ MessageModel.prototype.hasVisibleAttachments = function () { return !!_.find(this.attachments(), function (oAttachment) { return !oAttachment.isLinked; }); }; /** * @param {string} sCid * @return {*} */ MessageModel.prototype.findAttachmentByCid = function (sCid) { var oResult = null, aAttachments = this.attachments() ; if (Utils.isNonEmptyArray(aAttachments)) { sCid = sCid.replace(/^<+/, '').replace(/>+$/, ''); oResult = _.find(aAttachments, function (oAttachment) { return sCid === oAttachment.cidWithOutTags; }); } return oResult || null; }; /** * @param {string} sContentLocation * @return {*} */ MessageModel.prototype.findAttachmentByContentLocation = function (sContentLocation) { var oResult = null, aAttachments = this.attachments() ; if (Utils.isNonEmptyArray(aAttachments)) { oResult = _.find(aAttachments, function (oAttachment) { return sContentLocation === oAttachment.contentLocation; }); } return oResult || null; }; /** * @return {string} */ MessageModel.prototype.messageId = function () { return this.sMessageId; }; /** * @return {string} */ MessageModel.prototype.inReplyTo = function () { return this.sInReplyTo; }; /** * @return {string} */ MessageModel.prototype.references = function () { return this.sReferences; }; /** * @return {string} */ MessageModel.prototype.fromAsSingleEmail = function () { return Utils.isArray(this.from) && this.from[0] ? this.from[0].email : ''; }; /** * @return {string} */ MessageModel.prototype.viewLink = function () { return LinkBuilder.messageViewLink(this.requestHash);// TODO cjs }; /** * @return {string} */ MessageModel.prototype.downloadLink = function () { return LinkBuilder.messageDownloadLink(this.requestHash);// TODO cjs }; /** * @param {Object} oExcludeEmails * @return {Array} */ MessageModel.prototype.replyEmails = function (oExcludeEmails) { var aResult = [], oUnic = Utils.isUnd(oExcludeEmails) ? {} : oExcludeEmails ; MessageModel.replyHelper(this.replyTo, oUnic, aResult); if (0 === aResult.length) { MessageModel.replyHelper(this.from, oUnic, aResult); } return aResult; }; /** * @param {Object} oExcludeEmails * @return {Array.} */ MessageModel.prototype.replyAllEmails = function (oExcludeEmails) { var aToResult = [], aCcResult = [], oUnic = Utils.isUnd(oExcludeEmails) ? {} : oExcludeEmails ; MessageModel.replyHelper(this.replyTo, oUnic, aToResult); if (0 === aToResult.length) { MessageModel.replyHelper(this.from, oUnic, aToResult); } MessageModel.replyHelper(this.to, oUnic, aToResult); MessageModel.replyHelper(this.cc, oUnic, aCcResult); return [aToResult, aCcResult]; }; /** * @return {string} */ MessageModel.prototype.textBodyToString = function () { return this.body ? this.body.html() : ''; }; /** * @return {string} */ MessageModel.prototype.attachmentsToStringLine = function () { var aAttachLines = _.map(this.attachments(), function (oItem) { return oItem.fileName + ' (' + oItem.friendlySize + ')'; }); return aAttachLines && 0 < aAttachLines.length ? aAttachLines.join(', ') : ''; }; /** * @return {Object} */ MessageModel.prototype.getDataForWindowPopup = function () { return { 'popupFrom': this.fromToLine(false), 'popupTo': this.toToLine(false), 'popupCc': this.ccToLine(false), 'popupBcc': this.bccToLine(false), 'popupSubject': this.subject(), 'popupDate': this.fullFormatDateValue(), 'popupAttachments': this.attachmentsToStringLine(), 'popupBody': this.textBodyToString() }; }; /** * @param {boolean=} bPrint = false */ MessageModel.prototype.viewPopupMessage = function (bPrint) { Utils.windowPopupKnockout(this.getDataForWindowPopup(), 'PopupsWindowSimpleMessage', this.subject(), function (oPopupWin) { if (oPopupWin && oPopupWin.document && oPopupWin.document.body) { $('img.lazy', oPopupWin.document.body).each(function (iIndex, oImg) { var $oImg = $(oImg), sOrig = $oImg.data('original'), sSrc = $oImg.attr('src') ; if (0 <= iIndex && sOrig && !sSrc) { $oImg.attr('src', sOrig); } }); if (bPrint) { window.setTimeout(function () { oPopupWin.print(); }, 100); } } }); }; MessageModel.prototype.printMessage = function () { this.viewPopupMessage(true); }; /** * @returns {string} */ MessageModel.prototype.generateUid = function () { return this.folderFullNameRaw + '/' + this.uid; }; /** * @param {MessageModel} oMessage * @return {MessageModel} */ MessageModel.prototype.populateByMessageListItem = function (oMessage) { this.folderFullNameRaw = oMessage.folderFullNameRaw; this.uid = oMessage.uid; this.hash = oMessage.hash; this.requestHash = oMessage.requestHash; this.subject(oMessage.subject()); this.subjectPrefix(this.subjectPrefix()); this.subjectSuffix(this.subjectSuffix()); this.size(oMessage.size()); this.dateTimeStampInUTC(oMessage.dateTimeStampInUTC()); this.priority(oMessage.priority()); this.proxy = oMessage.proxy; this.fromEmailString(oMessage.fromEmailString()); this.fromClearEmailString(oMessage.fromClearEmailString()); this.toEmailsString(oMessage.toEmailsString()); this.toClearEmailsString(oMessage.toClearEmailsString()); this.emails = oMessage.emails; this.from = oMessage.from; this.to = oMessage.to; this.cc = oMessage.cc; this.bcc = oMessage.bcc; this.replyTo = oMessage.replyTo; this.deliveredTo = oMessage.deliveredTo; this.unseen(oMessage.unseen()); this.flagged(oMessage.flagged()); this.answered(oMessage.answered()); this.forwarded(oMessage.forwarded()); this.isReadReceipt(oMessage.isReadReceipt()); this.selected(oMessage.selected()); this.checked(oMessage.checked()); this.hasAttachments(oMessage.hasAttachments()); this.attachmentsMainType(oMessage.attachmentsMainType()); this.moment(oMessage.moment()); this.body = null; this.priority(Enums.MessagePriority.Normal); this.aDraftInfo = []; this.sMessageId = ''; this.sInReplyTo = ''; this.sReferences = ''; this.parentUid(oMessage.parentUid()); this.threads(oMessage.threads()); this.threadsLen(oMessage.threadsLen()); this.computeSenderEmail(); return this; }; MessageModel.prototype.showExternalImages = function (bLazy) { if (this.body && this.body.data('rl-has-images')) { var sAttr = ''; bLazy = Utils.isUnd(bLazy) ? false : bLazy; this.hasImages(false); this.body.data('rl-has-images', false); sAttr = this.proxy ? 'data-x-additional-src' : 'data-x-src'; $('[' + sAttr + ']', this.body).each(function () { if (bLazy && $(this).is('img')) { $(this) .addClass('lazy') .attr('data-original', $(this).attr(sAttr)) .removeAttr(sAttr) ; } else { $(this).attr('src', $(this).attr(sAttr)).removeAttr(sAttr); } }); sAttr = this.proxy ? 'data-x-additional-style-url' : 'data-x-style-url'; $('[' + sAttr + ']', this.body).each(function () { var sStyle = Utils.trim($(this).attr('style')); sStyle = '' === sStyle ? '' : (';' === sStyle.substr(-1) ? sStyle + ' ' : sStyle + '; '); $(this).attr('style', sStyle + $(this).attr(sAttr)).removeAttr(sAttr); }); if (bLazy) { $('img.lazy', this.body).addClass('lazy-inited').lazyload({ 'threshold' : 400, 'effect' : 'fadeIn', 'skip_invisible' : false, 'container': $('.RL-MailMessageView .messageView .messageItem .content')[0] }); $window.resize(); } Utils.windowResize(500); } }; MessageModel.prototype.showInternalImages = function (bLazy) { if (this.body && !this.body.data('rl-init-internal-images')) { this.body.data('rl-init-internal-images', true); bLazy = Utils.isUnd(bLazy) ? false : bLazy; var self = this; $('[data-x-src-cid]', this.body).each(function () { var oAttachment = self.findAttachmentByCid($(this).attr('data-x-src-cid')); if (oAttachment && oAttachment.download) { if (bLazy && $(this).is('img')) { $(this) .addClass('lazy') .attr('data-original', oAttachment.linkPreview()); } else { $(this).attr('src', oAttachment.linkPreview()); } } }); $('[data-x-src-location]', this.body).each(function () { var oAttachment = self.findAttachmentByContentLocation($(this).attr('data-x-src-location')); if (!oAttachment) { oAttachment = self.findAttachmentByCid($(this).attr('data-x-src-location')); } if (oAttachment && oAttachment.download) { if (bLazy && $(this).is('img')) { $(this) .addClass('lazy') .attr('data-original', oAttachment.linkPreview()); } else { $(this).attr('src', oAttachment.linkPreview()); } } }); $('[data-x-style-cid]', this.body).each(function () { var sStyle = '', sName = '', oAttachment = self.findAttachmentByCid($(this).attr('data-x-style-cid')) ; if (oAttachment && oAttachment.linkPreview) { sName = $(this).attr('data-x-style-cid-name'); if ('' !== sName) { sStyle = Utils.trim($(this).attr('style')); sStyle = '' === sStyle ? '' : (';' === sStyle.substr(-1) ? sStyle + ' ' : sStyle + '; '); $(this).attr('style', sStyle + sName + ': url(\'' + oAttachment.linkPreview() + '\')'); } } }); if (bLazy) { (function ($oImg, oContainer) { _.delay(function () { $oImg.addClass('lazy-inited').lazyload({ 'threshold' : 400, 'effect' : 'fadeIn', 'skip_invisible' : false, 'container': oContainer }); }, 300); }($('img.lazy', self.body), $('.RL-MailMessageView .messageView .messageItem .content')[0])); } Utils.windowResize(500); } }; MessageModel.prototype.storeDataToDom = function () { if (this.body) { this.body.data('rl-is-html', !!this.isHtml()); this.body.data('rl-has-images', !!this.hasImages()); this.body.data('rl-plain-raw', this.plainRaw); if (RL.data().capaOpenPGP()) // TODO cjs { this.body.data('rl-plain-pgp-signed', !!this.isPgpSigned()); this.body.data('rl-plain-pgp-encrypted', !!this.isPgpEncrypted()); this.body.data('rl-pgp-verify-status', this.pgpSignedVerifyStatus()); this.body.data('rl-pgp-verify-user', this.pgpSignedVerifyUser()); } } }; MessageModel.prototype.storePgpVerifyDataToDom = function () { if (this.body && RL.data().capaOpenPGP()) // TODO cjs { this.body.data('rl-pgp-verify-status', this.pgpSignedVerifyStatus()); this.body.data('rl-pgp-verify-user', this.pgpSignedVerifyUser()); } }; MessageModel.prototype.fetchDataToDom = function () { if (this.body) { this.isHtml(!!this.body.data('rl-is-html')); this.hasImages(!!this.body.data('rl-has-images')); this.plainRaw = Utils.pString(this.body.data('rl-plain-raw')); if (RL.data().capaOpenPGP()) // TODO cjs { this.isPgpSigned(!!this.body.data('rl-plain-pgp-signed')); this.isPgpEncrypted(!!this.body.data('rl-plain-pgp-encrypted')); this.pgpSignedVerifyStatus(this.body.data('rl-pgp-verify-status')); this.pgpSignedVerifyUser(this.body.data('rl-pgp-verify-user')); } else { this.isPgpSigned(false); this.isPgpEncrypted(false); this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.None); this.pgpSignedVerifyUser(''); } } }; MessageModel.prototype.verifyPgpSignedClearMessage = function () { if (this.isPgpSigned()) { var aRes = [], mPgpMessage = null, sFrom = this.from && this.from[0] && this.from[0].email ? this.from[0].email : '', aPublicKeys = RL.data().findPublicKeysByEmail(sFrom), // TODO cjs oValidKey = null, oValidSysKey = null, sPlain = '' ; this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Error); this.pgpSignedVerifyUser(''); try { mPgpMessage = window.openpgp.cleartext.readArmored(this.plainRaw); if (mPgpMessage && mPgpMessage.getText) { this.pgpSignedVerifyStatus( aPublicKeys.length ? Enums.SignedVerifyStatus.Unverified : Enums.SignedVerifyStatus.UnknownPublicKeys); aRes = mPgpMessage.verify(aPublicKeys); if (aRes && 0 < aRes.length) { oValidKey = _.find(aRes, function (oItem) { return oItem && oItem.keyid && oItem.valid; }); if (oValidKey) { oValidSysKey = RL.data().findPublicKeyByHex(oValidKey.keyid.toHex()); // TODO cjs if (oValidSysKey) { sPlain = mPgpMessage.getText(); this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Success); this.pgpSignedVerifyUser(oValidSysKey.user); sPlain = $div.empty().append( $('
').text(sPlain)
								   ).html()
							   ;

							   $div.empty();

							   this.replacePlaneTextBody(sPlain);
						   }
					   }
				   }
			   }
		   }
		   catch (oExc) {}

		   this.storePgpVerifyDataToDom();
	   }
	};

	MessageModel.prototype.decryptPgpEncryptedMessage = function (sPassword)
	{
	   if (this.isPgpEncrypted())
	   {
		   var
			   aRes = [],
			   mPgpMessage = null,
			   mPgpMessageDecrypted = null,
			   sFrom = this.from && this.from[0] && this.from[0].email ? this.from[0].email : '',
			   aPublicKey = RL.data().findPublicKeysByEmail(sFrom), // TODO cjs
			   oPrivateKey = RL.data().findSelfPrivateKey(sPassword), // TODO cjs
			   oValidKey = null,
			   oValidSysKey = null,
			   sPlain = ''
		   ;

		   this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Error);
		   this.pgpSignedVerifyUser('');

		   if (!oPrivateKey)
		   {
			   this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.UnknownPrivateKey);
		   }

		   try
		   {
			   mPgpMessage = window.openpgp.message.readArmored(this.plainRaw);
			   if (mPgpMessage && oPrivateKey && mPgpMessage.decrypt)
			   {
				   this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Unverified);

				   mPgpMessageDecrypted = mPgpMessage.decrypt(oPrivateKey);
				   if (mPgpMessageDecrypted)
				   {
					   aRes = mPgpMessageDecrypted.verify(aPublicKey);
					   if (aRes && 0 < aRes.length)
					   {
						   oValidKey = _.find(aRes, function (oItem) {
							   return oItem && oItem.keyid && oItem.valid;
						   });

						   if (oValidKey)
						   {
							   oValidSysKey = RL.data().findPublicKeyByHex(oValidKey.keyid.toHex()); // TODO cjs
							   if (oValidSysKey)
							   {
								   this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Success);
								   this.pgpSignedVerifyUser(oValidSysKey.user);
							   }
						   }
					   }

					   sPlain = mPgpMessageDecrypted.getText();

					   sPlain =
						   $div.empty().append(
							   $('
').text(sPlain)
						   ).html()
					   ;

					   $div.empty();

					   this.replacePlaneTextBody(sPlain);
				   }
			   }
		   }
		   catch (oExc) {}

		   this.storePgpVerifyDataToDom();
	   }
	};

	MessageModel.prototype.replacePlaneTextBody = function (sPlain)
	{
	   if (this.body)
	   {
		   this.body.html(sPlain).addClass('b-text-part plain');
	   }
	};

	/**
	* @return {string}
	*/
	MessageModel.prototype.flagHash = function ()
	{
	   return [this.deleted(), this.unseen(), this.flagged(), this.answered(), this.forwarded(),
		   this.isReadReceipt()].join('');
	};

	module.exports = MessageModel;

}(module));
},{"../Common/Enums.js":5,"../Common/LinkBuilder.js":7,"../Common/Utils.js":9,"../External/$div.js":10,"../External/$window.js":13,"../External/jquery.js":19,"../External/ko.js":21,"../External/moment.js":22,"../External/underscore.js":24,"../External/window.js":25,"./AttachmentModel.js":29,"./EmailModel.js":30}],32:[function(require,module,exports){
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */

'use strict';

module.exports = function () {
	return require('./Knoin/Knoin.js').rl();
};
},{"./Knoin/Knoin.js":26}],33:[function(require,module,exports){
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */

'use strict';

module.exports = function () {
	return require('./Knoin/Knoin.js').remote();
};
},{"./Knoin/Knoin.js":26}],34:[function(require,module,exports){
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */

(function (module) {

	'use strict';

	var
		window = require('../External/window.js'),
		$ = require('../External/jquery.js'),

		Consts = require('../Common/Consts.js'),
		Enums = require('../Common/Enums.js'),
		Globals = require('../Common/Globals.js'),
		Utils = require('../Common/Utils.js'),
		Plugins = require('../Common/Plugins.js'),
		LinkBuilder = require('../Common/LinkBuilder.js'),

		RL = require('../RL.js')
	;

	/**
	* @constructor
	*/
   function AbstractAjaxRemoteStorage()
   {
	   this.oRequests = {};
   }

   AbstractAjaxRemoteStorage.prototype.oRequests = {};

   /**
	* @param {?Function} fCallback
	* @param {string} sRequestAction
	* @param {string} sType
	* @param {?AjaxJsonDefaultResponse} oData
	* @param {boolean} bCached
	* @param {*=} oRequestParameters
	*/
   AbstractAjaxRemoteStorage.prototype.defaultResponse = function (fCallback, sRequestAction, sType, oData, bCached, oRequestParameters)
   {
	   var
		   fCall = function () {
			   if (Enums.StorageResultType.Success !== sType && Globals.bUnload)
			   {
				   sType = Enums.StorageResultType.Unload;
			   }

			   if (Enums.StorageResultType.Success === sType && oData && !oData.Result)
			   {
				   if (oData && -1 < Utils.inArray(oData.ErrorCode, [
					   Enums.Notification.AuthError, Enums.Notification.AccessError,
					   Enums.Notification.ConnectionError, Enums.Notification.DomainNotAllowed, Enums.Notification.AccountNotAllowed,
					   Enums.Notification.MailServerError,	Enums.Notification.UnknownNotification, Enums.Notification.UnknownError
				   ]))
				   {
					   Globals.iAjaxErrorCount++;
				   }

				   if (oData && Enums.Notification.InvalidToken === oData.ErrorCode)
				   {
					   Globals.iTokenErrorCount++;
				   }

				   if (Consts.Values.TokenErrorLimit < Globals.iTokenErrorCount)
				   {
					   RL().loginAndLogoutReload(true);
				   }

				   if (oData.Logout || Consts.Values.AjaxErrorLimit < Globals.iAjaxErrorCount)
				   {
					   if (window.__rlah_clear)
					   {
						   window.__rlah_clear();
					   }

					   RL().loginAndLogoutReload(true);
				   }
			   }
			   else if (Enums.StorageResultType.Success === sType && oData && oData.Result)
			   {
				   Globals.iAjaxErrorCount = 0;
				   Globals.iTokenErrorCount = 0;
			   }

			   if (fCallback)
			   {
				   Plugins.runHook('ajax-default-response', [sRequestAction, Enums.StorageResultType.Success === sType ? oData : null, sType, bCached, oRequestParameters]);

				   fCallback(
					   sType,
					   Enums.StorageResultType.Success === sType ? oData : null,
					   bCached,
					   sRequestAction,
					   oRequestParameters
				   );
			   }
		   }
	   ;

	   switch (sType)
	   {
		   case 'success':
			   sType = Enums.StorageResultType.Success;
			   break;
		   case 'abort':
			   sType = Enums.StorageResultType.Abort;
			   break;
		   default:
			   sType = Enums.StorageResultType.Error;
			   break;
	   }

	   if (Enums.StorageResultType.Error === sType)
	   {
		   _.delay(fCall, 300);
	   }
	   else
	   {
		   fCall();
	   }
   };

   /**
	* @param {?Function} fResultCallback
	* @param {Object} oParameters
	* @param {?number=} iTimeOut = 20000
	* @param {string=} sGetAdd = ''
	* @param {Array=} aAbortActions = []
	* @return {jQuery.jqXHR}
	*/
   AbstractAjaxRemoteStorage.prototype.ajaxRequest = function (fResultCallback, oParameters, iTimeOut, sGetAdd, aAbortActions)
   {
	   var
		   self = this,
		   bPost = '' === sGetAdd,
		   oHeaders = {},
		   iStart = (new window.Date()).getTime(),
		   oDefAjax = null,
		   sAction = ''
	   ;

	   oParameters = oParameters || {};
	   iTimeOut = Utils.isNormal(iTimeOut) ? iTimeOut : 20000;
	   sGetAdd = Utils.isUnd(sGetAdd) ? '' : Utils.pString(sGetAdd);
	   aAbortActions = Utils.isArray(aAbortActions) ? aAbortActions : [];

	   sAction = oParameters.Action || '';

	   if (sAction && 0 < aAbortActions.length)
	   {
		   _.each(aAbortActions, function (sActionToAbort) {
			   if (self.oRequests[sActionToAbort])
			   {
				   self.oRequests[sActionToAbort].__aborted = true;
				   if (self.oRequests[sActionToAbort].abort)
				   {
					   self.oRequests[sActionToAbort].abort();
				   }
				   self.oRequests[sActionToAbort] = null;
			   }
		   });
	   }

	   if (bPost)
	   {
		   oParameters['XToken'] = RL.settingsGet('Token'); // TODO cjs
	   }

	   oDefAjax = $.ajax({
		   'type': bPost ? 'POST' : 'GET',
		   'url': LinkBuilder.ajax(sGetAdd),
		   'async': true,
		   'dataType': 'json',
		   'data': bPost ? oParameters : {},
		   'headers': oHeaders,
		   'timeout': iTimeOut,
		   'global': true
	   });

	   oDefAjax.always(function (oData, sType) {

		   var bCached = false;
		   if (oData && oData['Time'])
		   {
			   bCached = Utils.pInt(oData['Time']) > (new window.Date()).getTime() - iStart;
		   }

		   if (sAction && self.oRequests[sAction])
		   {
			   if (self.oRequests[sAction].__aborted)
			   {
				   sType = 'abort';
			   }

			   self.oRequests[sAction] = null;
		   }

		   self.defaultResponse(fResultCallback, sAction, sType, oData, bCached, oParameters);
	   });

	   if (sAction && 0 < aAbortActions.length && -1 < Utils.inArray(sAction, aAbortActions))
	   {
		   if (this.oRequests[sAction])
		   {
			   this.oRequests[sAction].__aborted = true;
			   if (this.oRequests[sAction].abort)
			   {
				   this.oRequests[sAction].abort();
			   }
			   this.oRequests[sAction] = null;
		   }

		   this.oRequests[sAction] = oDefAjax;
	   }

	   return oDefAjax;
   };

   /**
	* @param {?Function} fCallback
	* @param {string} sAction
	* @param {Object=} oParameters
	* @param {?number=} iTimeout
	* @param {string=} sGetAdd = ''
	* @param {Array=} aAbortActions = []
	*/
   AbstractAjaxRemoteStorage.prototype.defaultRequest = function (fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions)
   {
	   oParameters = oParameters || {};
	   oParameters.Action = sAction;

	   sGetAdd = Utils.pString(sGetAdd);

	   Plugins.runHook('ajax-default-request', [sAction, oParameters, sGetAdd]);

	   this.ajaxRequest(fCallback, oParameters,
		   Utils.isUnd(iTimeout) ? Consts.Defaults.DefaultAjaxTimeout : Utils.pInt(iTimeout), sGetAdd, aAbortActions);
   };

   /**
	* @param {?Function} fCallback
	*/
   AbstractAjaxRemoteStorage.prototype.noop = function (fCallback)
   {
	   this.defaultRequest(fCallback, 'Noop');
   };

   /**
	* @param {?Function} fCallback
	* @param {string} sMessage
	* @param {string} sFileName
	* @param {number} iLineNo
	* @param {string} sLocation
	* @param {string} sHtmlCapa
	* @param {number} iTime
	*/
   AbstractAjaxRemoteStorage.prototype.jsError = function (fCallback, sMessage, sFileName, iLineNo, sLocation, sHtmlCapa, iTime)
   {
	   this.defaultRequest(fCallback, 'JsError', {
		   'Message': sMessage,
		   'FileName': sFileName,
		   'LineNo': iLineNo,
		   'Location': sLocation,
		   'HtmlCapa': sHtmlCapa,
		   'TimeOnPage': iTime
	   });
   };

   /**
	* @param {?Function} fCallback
	* @param {string} sType
	* @param {Array=} mData = null
	* @param {boolean=} bIsError = false
	*/
   AbstractAjaxRemoteStorage.prototype.jsInfo = function (fCallback, sType, mData, bIsError)
   {
	   this.defaultRequest(fCallback, 'JsInfo', {
		   'Type': sType,
		   'Data': mData,
		   'IsError': (Utils.isUnd(bIsError) ? false : !!bIsError) ? '1' : '0'
	   });
   };

   /**
	* @param {?Function} fCallback
	*/
   AbstractAjaxRemoteStorage.prototype.getPublicKey = function (fCallback)
   {
	   this.defaultRequest(fCallback, 'GetPublicKey');
   };

   /**
	* @param {?Function} fCallback
	* @param {string} sVersion
	*/
   AbstractAjaxRemoteStorage.prototype.jsVersion = function (fCallback, sVersion)
   {
	   this.defaultRequest(fCallback, 'Version', {
		   'Version': sVersion
	   });
   };

	module.exports = AbstractAjaxRemoteStorage;

}(module));
},{"../Common/Consts.js":4,"../Common/Enums.js":5,"../Common/Globals.js":6,"../Common/LinkBuilder.js":7,"../Common/Plugins.js":8,"../Common/Utils.js":9,"../External/jquery.js":19,"../External/window.js":25,"../RL.js":32}],35:[function(require,module,exports){
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */

(function (module) {

	'use strict';

	var
		ko = require('../External/ko.js'),
		key = require('../External/key.js'),
		Enums = require('../Common/Enums.js'),
		Globals = require('../Common/Globals.js'),
		Utils = require('../Common/Utils.js')
	;
	
	/**
	 * @constructor
	 */
	function AbstractData()
	{
		this.leftPanelDisabled = ko.observable(false);
		this.useKeyboardShortcuts = ko.observable(true);

		this.keyScopeReal = ko.observable(Enums.KeyState.All);
		this.keyScopeFake = ko.observable(Enums.KeyState.All);

		this.keyScope = ko.computed({
			'owner': this,
			'read': function () {
				return this.keyScopeFake();
			},
			'write': function (sValue) {

				if (Enums.KeyState.Menu !== sValue)
				{
					if (Enums.KeyState.Compose === sValue)
					{
						Utils.disableKeyFilter();
					}
					else
					{
						Utils.restoreKeyFilter();
					}

					this.keyScopeFake(sValue);
					if (Globals.dropdownVisibility())
					{
						sValue = Enums.KeyState.Menu;
					}
				}

				this.keyScopeReal(sValue);
			}
		});

		this.keyScopeReal.subscribe(function (sValue) {
	//		window.console.log(sValue);
			key.setScope(sValue);
		});

		this.leftPanelDisabled.subscribe(function (bValue) {
			RL.pub('left-panel.' + (bValue ? 'off' : 'on')); // TODO cjs
		});

		Globals.dropdownVisibility.subscribe(function (bValue) {
			if (bValue)
			{
				Globals.tooltipTrigger(!Globals.tooltipTrigger());
				this.keyScope(Enums.KeyState.Menu);
			}
			else if (Enums.KeyState.Menu === key.getScope())
			{
				this.keyScope(this.keyScopeFake());
			}
		}, this);

		Utils.initDataConstructorBySettings(this);
	}

	AbstractData.prototype.populateDataOnStart = function()
	{
		var
			mLayout = Utils.pInt(RL.settingsGet('Layout')), // TODO cjs
			aLanguages = RL.settingsGet('Languages'),
			aThemes = RL.settingsGet('Themes')
		;

		if (Utils.isArray(aLanguages))
		{
			this.languages(aLanguages);
		}

		if (Utils.isArray(aThemes))
		{
			this.themes(aThemes);
		}

		this.mainLanguage(RL.settingsGet('Language'));
		this.mainTheme(RL.settingsGet('Theme'));

		this.capaAdditionalAccounts(RL.capa(Enums.Capa.AdditionalAccounts));
		this.capaAdditionalIdentities(RL.capa(Enums.Capa.AdditionalIdentities));
		this.capaGravatar(RL.capa(Enums.Capa.Gravatar));
		this.determineUserLanguage(!!RL.settingsGet('DetermineUserLanguage'));
		this.determineUserDomain(!!RL.settingsGet('DetermineUserDomain'));

		this.capaThemes(RL.capa(Enums.Capa.Themes));
		this.allowLanguagesOnLogin(!!RL.settingsGet('AllowLanguagesOnLogin'));
		this.allowLanguagesOnSettings(!!RL.settingsGet('AllowLanguagesOnSettings'));
		this.useLocalProxyForExternalImages(!!RL.settingsGet('UseLocalProxyForExternalImages'));

		this.editorDefaultType(RL.settingsGet('EditorDefaultType'));
		this.showImages(!!RL.settingsGet('ShowImages'));
		this.contactsAutosave(!!RL.settingsGet('ContactsAutosave'));
		this.interfaceAnimation(RL.settingsGet('InterfaceAnimation'));

		this.mainMessagesPerPage(RL.settingsGet('MPP'));

		this.desktopNotifications(!!RL.settingsGet('DesktopNotifications'));
		this.useThreads(!!RL.settingsGet('UseThreads'));
		this.replySameFolder(!!RL.settingsGet('ReplySameFolder'));
		this.useCheckboxesInList(!!RL.settingsGet('UseCheckboxesInList'));

		this.layout(Enums.Layout.SidePreview);
		if (-1 < Utils.inArray(mLayout, [Enums.Layout.NoPreview, Enums.Layout.SidePreview, Enums.Layout.BottomPreview]))
		{
			this.layout(mLayout);
		}
		this.facebookSupported(!!RL.settingsGet('SupportedFacebookSocial'));
		this.facebookEnable(!!RL.settingsGet('AllowFacebookSocial'));
		this.facebookAppID(RL.settingsGet('FacebookAppID'));
		this.facebookAppSecret(RL.settingsGet('FacebookAppSecret'));

		this.twitterEnable(!!RL.settingsGet('AllowTwitterSocial'));
		this.twitterConsumerKey(RL.settingsGet('TwitterConsumerKey'));
		this.twitterConsumerSecret(RL.settingsGet('TwitterConsumerSecret'));

		this.googleEnable(!!RL.settingsGet('AllowGoogleSocial'));
		this.googleClientID(RL.settingsGet('GoogleClientID'));
		this.googleClientSecret(RL.settingsGet('GoogleClientSecret'));
		this.googleApiKey(RL.settingsGet('GoogleApiKey'));

		this.dropboxEnable(!!RL.settingsGet('AllowDropboxSocial'));
		this.dropboxApiKey(RL.settingsGet('DropboxApiKey'));

		this.contactsIsAllowed(!!RL.settingsGet('ContactsIsAllowed'));
	};

	module.exports = AbstractData;

}(module));
},{"../Common/Enums.js":5,"../Common/Globals.js":6,"../Common/Utils.js":9,"../External/key.js":20,"../External/ko.js":21}],36:[function(require,module,exports){
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */

(function (module) {

	'use strict';

	var
		_ = require('../External/underscore.js'),
		CookieDriver = require('./LocalStorages/CookieDriver.js'),
		LocalStorageDriver = require('./LocalStorages/LocalStorageDriver.js')
	;

	/**
	 * @constructor
	 */
	function LocalStorage()
	{
		var
			NextStorageDriver = _.find([LocalStorageDriver, CookieDriver], function (NextStorageDriver) {
				return NextStorageDriver.supported();
			})
		;

		if (NextStorageDriver)
		{
			NextStorageDriver = /** @type {?Function} */ NextStorageDriver;
			this.oDriver = new NextStorageDriver();
		}
	}

	LocalStorage.prototype.oDriver = null;

	/**
	 * @param {number} iKey
	 * @param {*} mData
	 * @return {boolean}
	 */
	LocalStorage.prototype.set = function (iKey, mData)
	{
		return this.oDriver ? this.oDriver.set('p' + iKey, mData) : false;
	};

	/**
	 * @param {number} iKey
	 * @return {*}
	 */
	LocalStorage.prototype.get = function (iKey)
	{
		return this.oDriver ? this.oDriver.get('p' + iKey) : null;
	};

	module.exports = new LocalStorage();

}(module));
},{"../External/underscore.js":24,"./LocalStorages/CookieDriver.js":37,"./LocalStorages/LocalStorageDriver.js":38}],37:[function(require,module,exports){
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */

(function (module) {

	'use strict';

	var
		$ = require('../../External/jquery.js'),
		JSON = require('../../External/JSON.js'),
		Consts = require('../../Common/Consts.js'),
		Utils = require('../../Common/Utils.js')
	;

	/**
	 * @constructor
	 */
	function CookieDriver()
	{

	}

	CookieDriver.supported = function ()
	{
		return true;
	};

	/**
	 * @param {string} sKey
	 * @param {*} mData
	 * @returns {boolean}
	 */
	CookieDriver.prototype.set = function (sKey, mData)
	{
		var
			mCokieValue = $.cookie(Consts.Values.ClientSideCookieIndexName),
			bResult = false,
			mResult = null
		;

		try
		{
			mResult = null === mCokieValue ? null : JSON.parse(mCokieValue);
			if (!mResult)
			{
				mResult = {};
			}

			mResult[sKey] = mData;
			$.cookie(Consts.Values.ClientSideCookieIndexName, JSON.stringify(mResult), {
				'expires': 30
			});

			bResult = true;
		}
		catch (oException) {}

		return bResult;
	};

	/**
	 * @param {string} sKey
	 * @returns {*}
	 */
	CookieDriver.prototype.get = function (sKey)
	{
		var
			mCokieValue = $.cookie(Consts.Values.ClientSideCookieIndexName),
			mResult = null
		;

		try
		{
			mResult = null === mCokieValue ? null : JSON.parse(mCokieValue);
			if (mResult && !Utils.isUnd(mResult[sKey]))
			{
				mResult = mResult[sKey];
			}
			else
			{
				mResult = null;
			}
		}
		catch (oException) {}

		return mResult;
	};

	module.exports = CookieDriver;

}(module));
},{"../../Common/Consts.js":4,"../../Common/Utils.js":9,"../../External/JSON.js":15,"../../External/jquery.js":19}],38:[function(require,module,exports){
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */

(function (module) {

	'use strict';

	var
		window = require('../../External/window.js'),
		JSON = require('../../External/JSON.js'),
		Consts = require('../../Common/Consts.js'),
		Utils = require('../../Common/Utils.js')
	;

	/**
	 * @constructor
	 */
	function LocalStorageDriver()
	{
	}

	LocalStorageDriver.supported = function ()
	{
		return !!window.localStorage;
	};

	/**
	 * @param {string} sKey
	 * @param {*} mData
	 * @returns {boolean}
	 */
	LocalStorageDriver.prototype.set = function (sKey, mData)
	{
		var
			mCookieValue = window.localStorage[Consts.Values.ClientSideCookieIndexName] || null,
			bResult = false,
			mResult = null
		;

		try
		{
			mResult = null === mCookieValue ? null : JSON.parse(mCookieValue);
			if (!mResult)
			{
				mResult = {};
			}

			mResult[sKey] = mData;
			window.localStorage[Consts.Values.ClientSideCookieIndexName] = JSON.stringify(mResult);

			bResult = true;
		}
		catch (oException) {}

		return bResult;
	};

	/**
	 * @param {string} sKey
	 * @returns {*}
	 */
	LocalStorageDriver.prototype.get = function (sKey)
	{
		var
			mCokieValue = window.localStorage[Consts.Values.ClientSideCookieIndexName] || null,
			mResult = null
		;

		try
		{
			mResult = null === mCokieValue ? null : JSON.parse(mCokieValue);
			if (mResult && !Utils.isUnd(mResult[sKey]))
			{
				mResult = mResult[sKey];
			}
			else
			{
				mResult = null;
			}
		}
		catch (oException) {}

		return mResult;
	};
	
	module.exports = LocalStorageDriver;

}(module));
},{"../../Common/Consts.js":4,"../../Common/Utils.js":9,"../../External/JSON.js":15,"../../External/window.js":25}],39:[function(require,module,exports){
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */

(function (module) {

	'use strict';

	var
		_ = require('../External/underscore.js'),

		Utils = require('../Common/Utils.js'),

		Cache = require('../Storages/WebMailCacheStorage.js'),
		
		AbstractAjaxRemoteStorage = require('./AbstractAjaxRemoteStorage.js')
	;

	/**
	 * @constructor
	 * @extends AbstractAjaxRemoteStorage
	 */
	function WebMailAjaxRemoteStorage()
	{
		AbstractAjaxRemoteStorage.call(this);

		this.oRequests = {};
	}

	_.extend(WebMailAjaxRemoteStorage.prototype, AbstractAjaxRemoteStorage.prototype);

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.folders = function (fCallback)
	{
		this.defaultRequest(fCallback, 'Folders', {
			'SentFolder': RL.settingsGet('SentFolder'),
			'DraftFolder': RL.settingsGet('DraftFolder'),
			'SpamFolder': RL.settingsGet('SpamFolder'),
			'TrashFolder': RL.settingsGet('TrashFolder'),
			'ArchiveFolder': RL.settingsGet('ArchiveFolder')
		}, null, '', ['Folders']);
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sEmail
	 * @param {string} sLogin
	 * @param {string} sPassword
	 * @param {boolean} bSignMe
	 * @param {string=} sLanguage
	 * @param {string=} sAdditionalCode
	 * @param {boolean=} bAdditionalCodeSignMe
	 */
	WebMailAjaxRemoteStorage.prototype.login = function (fCallback, sEmail, sLogin, sPassword, bSignMe, sLanguage, sAdditionalCode, bAdditionalCodeSignMe)
	{
		this.defaultRequest(fCallback, 'Login', {
			'Email': sEmail,
			'Login': sLogin,
			'Password': sPassword,
			'Language': sLanguage || '',
			'AdditionalCode': sAdditionalCode || '',
			'AdditionalCodeSignMe': bAdditionalCodeSignMe ? '1' : '0',
			'SignMe': bSignMe ? '1' : '0'
		});
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.getTwoFactor = function (fCallback)
	{
		this.defaultRequest(fCallback, 'GetTwoFactorInfo');
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.createTwoFactor = function (fCallback)
	{
		this.defaultRequest(fCallback, 'CreateTwoFactorSecret');
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.clearTwoFactor = function (fCallback)
	{
		this.defaultRequest(fCallback, 'ClearTwoFactorInfo');
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.showTwoFactorSecret = function (fCallback)
	{
		this.defaultRequest(fCallback, 'ShowTwoFactorSecret');
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sCode
	 */
	WebMailAjaxRemoteStorage.prototype.testTwoFactor = function (fCallback, sCode)
	{
		this.defaultRequest(fCallback, 'TestTwoFactorInfo', {
			'Code': sCode
		});
	};

	/**
	 * @param {?Function} fCallback
	 * @param {boolean} bEnable
	 */
	WebMailAjaxRemoteStorage.prototype.enableTwoFactor = function (fCallback, bEnable)
	{
		this.defaultRequest(fCallback, 'EnableTwoFactor', {
			'Enable': bEnable ? '1' : '0'
		});
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.clearTwoFactorInfo = function (fCallback)
	{
		this.defaultRequest(fCallback, 'ClearTwoFactorInfo');
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.contactsSync = function (fCallback)
	{
		this.defaultRequest(fCallback, 'ContactsSync', null, Consts.Defaults.ContactsSyncAjaxTimeout);
	};

	/**
	 * @param {?Function} fCallback
	 * @param {boolean} bEnable
	 * @param {string} sUrl
	 * @param {string} sUser
	 * @param {string} sPassword
	 */
	WebMailAjaxRemoteStorage.prototype.saveContactsSyncData = function (fCallback, bEnable, sUrl, sUser, sPassword)
	{
		this.defaultRequest(fCallback, 'SaveContactsSyncData', {
			'Enable': bEnable ? '1' : '0',
			'Url': sUrl,
			'User': sUser,
			'Password': sPassword
		});
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sEmail
	 * @param {string} sLogin
	 * @param {string} sPassword
	 */
	WebMailAjaxRemoteStorage.prototype.accountAdd = function (fCallback, sEmail, sLogin, sPassword)
	{
		this.defaultRequest(fCallback, 'AccountAdd', {
			'Email': sEmail,
			'Login': sLogin,
			'Password': sPassword
		});
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sEmailToDelete
	 */
	WebMailAjaxRemoteStorage.prototype.accountDelete = function (fCallback, sEmailToDelete)
	{
		this.defaultRequest(fCallback, 'AccountDelete', {
			'EmailToDelete': sEmailToDelete
		});
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sId
	 * @param {string} sEmail
	 * @param {string} sName
	 * @param {string} sReplyTo
	 * @param {string} sBcc
	 */
	WebMailAjaxRemoteStorage.prototype.identityUpdate = function (fCallback, sId, sEmail, sName, sReplyTo, sBcc)
	{
		this.defaultRequest(fCallback, 'IdentityUpdate', {
			'Id': sId,
			'Email': sEmail,
			'Name': sName,
			'ReplyTo': sReplyTo,
			'Bcc': sBcc
		});
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sIdToDelete
	 */
	WebMailAjaxRemoteStorage.prototype.identityDelete = function (fCallback, sIdToDelete)
	{
		this.defaultRequest(fCallback, 'IdentityDelete', {
			'IdToDelete': sIdToDelete
		});
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.accountsAndIdentities = function (fCallback)
	{
		this.defaultRequest(fCallback, 'AccountsAndIdentities');
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sFolderFullNameRaw
	 * @param {number=} iOffset = 0
	 * @param {number=} iLimit = 20
	 * @param {string=} sSearch = ''
	 * @param {boolean=} bSilent = false
	 */
	WebMailAjaxRemoteStorage.prototype.messageList = function (fCallback, sFolderFullNameRaw, iOffset, iLimit, sSearch, bSilent)
	{
		sFolderFullNameRaw = Utils.pString(sFolderFullNameRaw);

		var
			oData = RL.data(),
			sFolderHash = Cache.getFolderHash(sFolderFullNameRaw)
		;

		bSilent = Utils.isUnd(bSilent) ? false : !!bSilent;
		iOffset = Utils.isUnd(iOffset) ? 0 : Utils.pInt(iOffset);
		iLimit = Utils.isUnd(iOffset) ? 20 : Utils.pInt(iLimit);
		sSearch = Utils.pString(sSearch);

		if ('' !== sFolderHash && ('' === sSearch || -1 === sSearch.indexOf('is:')))
		{
			this.defaultRequest(fCallback, 'MessageList', {},
				'' === sSearch ? Consts.Defaults.DefaultAjaxTimeout : Consts.Defaults.SearchAjaxTimeout,
				'MessageList/' + Base64.urlsafe_encode([
					sFolderFullNameRaw,
					iOffset,
					iLimit,
					sSearch,
					oData.projectHash(),
					sFolderHash,
					'INBOX' === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
					oData.threading() && oData.useThreads() ? '1' : '0',
					oData.threading() && sFolderFullNameRaw === oData.messageListThreadFolder() ? oData.messageListThreadUids().join(',') : ''
				].join(String.fromCharCode(0))), bSilent ? [] : ['MessageList']);
		}
		else
		{
			this.defaultRequest(fCallback, 'MessageList', {
				'Folder': sFolderFullNameRaw,
				'Offset': iOffset,
				'Limit': iLimit,
				'Search': sSearch,
				'UidNext': 'INBOX' === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
				'UseThreads': RL.data().threading() && RL.data().useThreads() ? '1' : '0',
				'ExpandedThreadUid': oData.threading() && sFolderFullNameRaw === oData.messageListThreadFolder() ? oData.messageListThreadUids().join(',') : ''
			}, '' === sSearch ? Consts.Defaults.DefaultAjaxTimeout : Consts.Defaults.SearchAjaxTimeout, '', bSilent ? [] : ['MessageList']);
		}
	};

	/**
	 * @param {?Function} fCallback
	 * @param {Array} aDownloads
	 */
	WebMailAjaxRemoteStorage.prototype.messageUploadAttachments = function (fCallback, aDownloads)
	{
		this.defaultRequest(fCallback, 'MessageUploadAttachments', {
			'Attachments': aDownloads
		}, 999000);
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sFolderFullNameRaw
	 * @param {number} iUid
	 * @return {boolean}
	 */
	WebMailAjaxRemoteStorage.prototype.message = function (fCallback, sFolderFullNameRaw, iUid)
	{
		sFolderFullNameRaw = Utils.pString(sFolderFullNameRaw);
		iUid = Utils.pInt(iUid);

		if (Cache.getFolderFromCacheList(sFolderFullNameRaw) && 0 < iUid)
		{
			this.defaultRequest(fCallback, 'Message', {}, null,
				'Message/' + Base64.urlsafe_encode([
					sFolderFullNameRaw,
					iUid,
					RL.data().projectHash(),
					RL.data().threading() && RL.data().useThreads() ? '1' : '0'
				].join(String.fromCharCode(0))), ['Message']);

			return true;
		}

		return false;
	};

	/**
	 * @param {?Function} fCallback
	 * @param {Array} aExternals
	 */
	WebMailAjaxRemoteStorage.prototype.composeUploadExternals = function (fCallback, aExternals)
	{
		this.defaultRequest(fCallback, 'ComposeUploadExternals', {
			'Externals': aExternals
		}, 999000);
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sUrl
	 * @param {string} sAccessToken
	 */
	WebMailAjaxRemoteStorage.prototype.composeUploadDrive = function (fCallback, sUrl, sAccessToken)
	{
		this.defaultRequest(fCallback, 'ComposeUploadDrive', {
			'AccessToken': sAccessToken,
			'Url': sUrl
		}, 999000);
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sFolder
	 * @param {Array=} aList = []
	 */
	WebMailAjaxRemoteStorage.prototype.folderInformation = function (fCallback, sFolder, aList)
	{
		var
			bRequest = true,
			aUids = []
		;

		if (Utils.isArray(aList) && 0 < aList.length)
		{
			bRequest = false;
			_.each(aList, function (oMessageListItem) {
				if (!Cache.getMessageFlagsFromCache(oMessageListItem.folderFullNameRaw, oMessageListItem.uid))
				{
					aUids.push(oMessageListItem.uid);
				}

				if (0 < oMessageListItem.threads().length)
				{
					_.each(oMessageListItem.threads(), function (sUid) {
						if (!Cache.getMessageFlagsFromCache(oMessageListItem.folderFullNameRaw, sUid))
						{
							aUids.push(sUid);
						}
					});
				}
			});

			if (0 < aUids.length)
			{
				bRequest = true;
			}
		}

		if (bRequest)
		{
			this.defaultRequest(fCallback, 'FolderInformation', {
				'Folder': sFolder,
				'FlagsUids': Utils.isArray(aUids) ? aUids.join(',') : '',
				'UidNext': 'INBOX' === sFolder ? Cache.getFolderUidNext(sFolder) : ''
			});
		}
		else if (RL.data().useThreads())
		{
			RL.reloadFlagsCurrentMessageListAndMessageFromCache();
		}
	};

	/**
	 * @param {?Function} fCallback
	 * @param {Array} aFolders
	 */
	WebMailAjaxRemoteStorage.prototype.folderInformationMultiply = function (fCallback, aFolders)
	{
		this.defaultRequest(fCallback, 'FolderInformationMultiply', {
			'Folders': aFolders
		});
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.logout = function (fCallback)
	{
		this.defaultRequest(fCallback, 'Logout');
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sFolderFullNameRaw
	 * @param {Array} aUids
	 * @param {boolean} bSetFlagged
	 */
	WebMailAjaxRemoteStorage.prototype.messageSetFlagged = function (fCallback, sFolderFullNameRaw, aUids, bSetFlagged)
	{
		this.defaultRequest(fCallback, 'MessageSetFlagged', {
			'Folder': sFolderFullNameRaw,
			'Uids': aUids.join(','),
			'SetAction': bSetFlagged ? '1' : '0'
		});
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sFolderFullNameRaw
	 * @param {Array} aUids
	 * @param {boolean} bSetSeen
	 */
	WebMailAjaxRemoteStorage.prototype.messageSetSeen = function (fCallback, sFolderFullNameRaw, aUids, bSetSeen)
	{
		this.defaultRequest(fCallback, 'MessageSetSeen', {
			'Folder': sFolderFullNameRaw,
			'Uids': aUids.join(','),
			'SetAction': bSetSeen ? '1' : '0'
		});
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sFolderFullNameRaw
	 * @param {boolean} bSetSeen
	 */
	WebMailAjaxRemoteStorage.prototype.messageSetSeenToAll = function (fCallback, sFolderFullNameRaw, bSetSeen)
	{
		this.defaultRequest(fCallback, 'MessageSetSeenToAll', {
			'Folder': sFolderFullNameRaw,
			'SetAction': bSetSeen ? '1' : '0'
		});
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sMessageFolder
	 * @param {string} sMessageUid
	 * @param {string} sDraftFolder
	 * @param {string} sFrom
	 * @param {string} sTo
	 * @param {string} sCc
	 * @param {string} sBcc
	 * @param {string} sSubject
	 * @param {boolean} bTextIsHtml
	 * @param {string} sText
	 * @param {Array} aAttachments
	 * @param {(Array|null)} aDraftInfo
	 * @param {string} sInReplyTo
	 * @param {string} sReferences
	 */
	WebMailAjaxRemoteStorage.prototype.saveMessage = function (fCallback, sMessageFolder, sMessageUid, sDraftFolder,
		sFrom, sTo, sCc, sBcc, sSubject, bTextIsHtml, sText, aAttachments, aDraftInfo, sInReplyTo, sReferences)
	{
		this.defaultRequest(fCallback, 'SaveMessage', {
			'MessageFolder': sMessageFolder,
			'MessageUid': sMessageUid,
			'DraftFolder': sDraftFolder,
			'From': sFrom,
			'To': sTo,
			'Cc': sCc,
			'Bcc': sBcc,
			'Subject': sSubject,
			'TextIsHtml': bTextIsHtml ? '1' : '0',
			'Text': sText,
			'DraftInfo': aDraftInfo,
			'InReplyTo': sInReplyTo,
			'References': sReferences,
			'Attachments': aAttachments
		}, Consts.Defaults.SaveMessageAjaxTimeout);
	};


	/**
	 * @param {?Function} fCallback
	 * @param {string} sMessageFolder
	 * @param {string} sMessageUid
	 * @param {string} sReadReceipt
	 * @param {string} sSubject
	 * @param {string} sText
	 */
	WebMailAjaxRemoteStorage.prototype.sendReadReceiptMessage = function (fCallback, sMessageFolder, sMessageUid, sReadReceipt, sSubject, sText)
	{
		this.defaultRequest(fCallback, 'SendReadReceiptMessage', {
			'MessageFolder': sMessageFolder,
			'MessageUid': sMessageUid,
			'ReadReceipt': sReadReceipt,
			'Subject': sSubject,
			'Text': sText
		});
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sMessageFolder
	 * @param {string} sMessageUid
	 * @param {string} sSentFolder
	 * @param {string} sFrom
	 * @param {string} sTo
	 * @param {string} sCc
	 * @param {string} sBcc
	 * @param {string} sSubject
	 * @param {boolean} bTextIsHtml
	 * @param {string} sText
	 * @param {Array} aAttachments
	 * @param {(Array|null)} aDraftInfo
	 * @param {string} sInReplyTo
	 * @param {string} sReferences
	 * @param {boolean} bRequestReadReceipt
	 */
	WebMailAjaxRemoteStorage.prototype.sendMessage = function (fCallback, sMessageFolder, sMessageUid, sSentFolder,
		sFrom, sTo, sCc, sBcc, sSubject, bTextIsHtml, sText, aAttachments, aDraftInfo, sInReplyTo, sReferences, bRequestReadReceipt)
	{
		this.defaultRequest(fCallback, 'SendMessage', {
			'MessageFolder': sMessageFolder,
			'MessageUid': sMessageUid,
			'SentFolder': sSentFolder,
			'From': sFrom,
			'To': sTo,
			'Cc': sCc,
			'Bcc': sBcc,
			'Subject': sSubject,
			'TextIsHtml': bTextIsHtml ? '1' : '0',
			'Text': sText,
			'DraftInfo': aDraftInfo,
			'InReplyTo': sInReplyTo,
			'References': sReferences,
			'ReadReceiptRequest': bRequestReadReceipt ? '1' : '0',
			'Attachments': aAttachments
		}, Consts.Defaults.SendMessageAjaxTimeout);
	};

	/**
	 * @param {?Function} fCallback
	 * @param {Object} oData
	 */
	WebMailAjaxRemoteStorage.prototype.saveSystemFolders = function (fCallback, oData)
	{
		this.defaultRequest(fCallback, 'SystemFoldersUpdate', oData);
	};

	/**
	 * @param {?Function} fCallback
	 * @param {Object} oData
	 */
	WebMailAjaxRemoteStorage.prototype.saveSettings = function (fCallback, oData)
	{
		this.defaultRequest(fCallback, 'SettingsUpdate', oData);
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sPrevPassword
	 * @param {string} sNewPassword
	 */
	WebMailAjaxRemoteStorage.prototype.changePassword = function (fCallback, sPrevPassword, sNewPassword)
	{
		this.defaultRequest(fCallback, 'ChangePassword', {
			'PrevPassword': sPrevPassword,
			'NewPassword': sNewPassword
		});
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sNewFolderName
	 * @param {string} sParentName
	 */
	WebMailAjaxRemoteStorage.prototype.folderCreate = function (fCallback, sNewFolderName, sParentName)
	{
		this.defaultRequest(fCallback, 'FolderCreate', {
			'Folder': sNewFolderName,
			'Parent': sParentName
		}, null, '', ['Folders']);
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sFolderFullNameRaw
	 */
	WebMailAjaxRemoteStorage.prototype.folderDelete = function (fCallback, sFolderFullNameRaw)
	{
		this.defaultRequest(fCallback, 'FolderDelete', {
			'Folder': sFolderFullNameRaw
		}, null, '', ['Folders']);
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sPrevFolderFullNameRaw
	 * @param {string} sNewFolderName
	 */
	WebMailAjaxRemoteStorage.prototype.folderRename = function (fCallback, sPrevFolderFullNameRaw, sNewFolderName)
	{
		this.defaultRequest(fCallback, 'FolderRename', {
			'Folder': sPrevFolderFullNameRaw,
			'NewFolderName': sNewFolderName
		}, null, '', ['Folders']);
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sFolderFullNameRaw
	 */
	WebMailAjaxRemoteStorage.prototype.folderClear = function (fCallback, sFolderFullNameRaw)
	{
		this.defaultRequest(fCallback, 'FolderClear', {
			'Folder': sFolderFullNameRaw
		});
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sFolderFullNameRaw
	 * @param {boolean} bSubscribe
	 */
	WebMailAjaxRemoteStorage.prototype.folderSetSubscribe = function (fCallback, sFolderFullNameRaw, bSubscribe)
	{
		this.defaultRequest(fCallback, 'FolderSubscribe', {
			'Folder': sFolderFullNameRaw,
			'Subscribe': bSubscribe ? '1' : '0'
		});
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sFolder
	 * @param {string} sToFolder
	 * @param {Array} aUids
	 * @param {string=} sLearning
	 */
	WebMailAjaxRemoteStorage.prototype.messagesMove = function (fCallback, sFolder, sToFolder, aUids, sLearning)
	{
		this.defaultRequest(fCallback, 'MessageMove', {
			'FromFolder': sFolder,
			'ToFolder': sToFolder,
			'Uids': aUids.join(','),
			'Learning': sLearning || ''
		}, null, '', ['MessageList']);
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sFolder
	 * @param {string} sToFolder
	 * @param {Array} aUids
	 */
	WebMailAjaxRemoteStorage.prototype.messagesCopy = function (fCallback, sFolder, sToFolder, aUids)
	{
		this.defaultRequest(fCallback, 'MessageCopy', {
			'FromFolder': sFolder,
			'ToFolder': sToFolder,
			'Uids': aUids.join(',')
		});
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sFolder
	 * @param {Array} aUids
	 */
	WebMailAjaxRemoteStorage.prototype.messagesDelete = function (fCallback, sFolder, aUids)
	{
		this.defaultRequest(fCallback, 'MessageDelete', {
			'Folder': sFolder,
			'Uids': aUids.join(',')
		}, null, '', ['MessageList']);
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.appDelayStart = function (fCallback)
	{
		this.defaultRequest(fCallback, 'AppDelayStart');
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.quota = function (fCallback)
	{
		this.defaultRequest(fCallback, 'Quota');
	};

	/**
	 * @param {?Function} fCallback
	 * @param {number} iOffset
	 * @param {number} iLimit
	 * @param {string} sSearch
	 */
	WebMailAjaxRemoteStorage.prototype.contacts = function (fCallback, iOffset, iLimit, sSearch)
	{
		this.defaultRequest(fCallback, 'Contacts', {
			'Offset': iOffset,
			'Limit': iLimit,
			'Search': sSearch
		}, null, '', ['Contacts']);
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.contactSave = function (fCallback, sRequestUid, sUid, sTags, aProperties)
	{
		this.defaultRequest(fCallback, 'ContactSave', {
			'RequestUid': sRequestUid,
			'Uid': Utils.trim(sUid),
			'Tags': Utils.trim(sTags),
			'Properties': aProperties
		});
	};

	/**
	 * @param {?Function} fCallback
	 * @param {Array} aUids
	 */
	WebMailAjaxRemoteStorage.prototype.contactsDelete = function (fCallback, aUids)
	{
		this.defaultRequest(fCallback, 'ContactsDelete', {
			'Uids': aUids.join(',')
		});
	};

	/**
	 * @param {?Function} fCallback
	 * @param {string} sQuery
	 * @param {number} iPage
	 */
	WebMailAjaxRemoteStorage.prototype.suggestions = function (fCallback, sQuery, iPage)
	{
		this.defaultRequest(fCallback, 'Suggestions', {
			'Query': sQuery,
			'Page': iPage
		}, null, '', ['Suggestions']);
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.facebookUser = function (fCallback)
	{
		this.defaultRequest(fCallback, 'SocialFacebookUserInformation');
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.facebookDisconnect = function (fCallback)
	{
		this.defaultRequest(fCallback, 'SocialFacebookDisconnect');
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.twitterUser = function (fCallback)
	{
		this.defaultRequest(fCallback, 'SocialTwitterUserInformation');
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.twitterDisconnect = function (fCallback)
	{
		this.defaultRequest(fCallback, 'SocialTwitterDisconnect');
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.googleUser = function (fCallback)
	{
		this.defaultRequest(fCallback, 'SocialGoogleUserInformation');
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.googleDisconnect = function (fCallback)
	{
		this.defaultRequest(fCallback, 'SocialGoogleDisconnect');
	};

	/**
	 * @param {?Function} fCallback
	 */
	WebMailAjaxRemoteStorage.prototype.socialUsers = function (fCallback)
	{
		this.defaultRequest(fCallback, 'SocialUsers');
	};

	module.exports = new WebMailAjaxRemoteStorage();

}(module));
},{"../Common/Utils.js":9,"../External/underscore.js":24,"../Storages/WebMailCacheStorage.js":40,"./AbstractAjaxRemoteStorage.js":34}],40:[function(require,module,exports){
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */

(function (module) {

	'use strict';

	var
		_ = require('../External/underscore.js'),
		
		Enums = require('../Common/Enums.js'),
		Utils = require('../Common/Utils.js'),
		LinkBuilder = require('../Common/LinkBuilder.js'),

		RL = require('../RL.js')
	;

	/**
	 * @constructor
	 */
	function WebMailCacheStorage()
	{
		this.oFoldersCache = {};
		this.oFoldersNamesCache = {};
		this.oFolderHashCache = {};
		this.oFolderUidNextCache = {};
		this.oMessageListHashCache = {};
		this.oMessageFlagsCache = {};
		this.oNewMessage = {};
		this.oRequestedMessage = {};

		this.bCapaGravatar = RL().capa(Enums.Capa.Gravatar);
	}

	/**
	 * @type {boolean}
	 */
	WebMailCacheStorage.prototype.bCapaGravatar = false;

	/**
	 * @type {Object}
	 */
	WebMailCacheStorage.prototype.oFoldersCache = {};

	/**
	 * @type {Object}
	 */
	WebMailCacheStorage.prototype.oFoldersNamesCache = {};

	/**
	 * @type {Object}
	 */
	WebMailCacheStorage.prototype.oFolderHashCache = {};

	/**
	 * @type {Object}
	 */
	WebMailCacheStorage.prototype.oFolderUidNextCache = {};

	/**
	 * @type {Object}
	 */
	WebMailCacheStorage.prototype.oMessageListHashCache = {};

	/**
	 * @type {Object}
	 */
	WebMailCacheStorage.prototype.oMessageFlagsCache = {};

	/**
	 * @type {Object}
	 */
	WebMailCacheStorage.prototype.oBodies = {};

	/**
	 * @type {Object}
	 */
	WebMailCacheStorage.prototype.oNewMessage = {};

	/**
	 * @type {Object}
	 */
	WebMailCacheStorage.prototype.oRequestedMessage = {};

	WebMailCacheStorage.prototype.clear = function ()
	{
		this.oFoldersCache = {};
		this.oFoldersNamesCache = {};
		this.oFolderHashCache = {};
		this.oFolderUidNextCache = {};
		this.oMessageListHashCache = {};
		this.oMessageFlagsCache = {};
		this.oBodies = {};
	};


	/**
	 * @param {string} sEmail
	 * @param {Function} fCallback
	 * @return {string}
	 */
	WebMailCacheStorage.prototype.getUserPic = function (sEmail, fCallback)
	{
		sEmail = Utils.trim(sEmail);
		fCallback(this.bCapaGravatar && '' !== sEmail ? LinkBuilder.avatarLink(sEmail) : '', sEmail);
	};

	/**
	 * @param {string} sFolderFullNameRaw
	 * @param {string} sUid
	 * @return {string}
	 */
	WebMailCacheStorage.prototype.getMessageKey = function (sFolderFullNameRaw, sUid)
	{
		return sFolderFullNameRaw + '#' + sUid;
	};

	/**
	 * @param {string} sFolder
	 * @param {string} sUid
	 */
	WebMailCacheStorage.prototype.addRequestedMessage = function (sFolder, sUid)
	{
		this.oRequestedMessage[this.getMessageKey(sFolder, sUid)] = true;
	};

	/**
	 * @param {string} sFolder
	 * @param {string} sUid
	 * @return {boolean}
	 */
	WebMailCacheStorage.prototype.hasRequestedMessage = function (sFolder, sUid)
	{
		return true === this.oRequestedMessage[this.getMessageKey(sFolder, sUid)];
	};

	/**
	 * @param {string} sFolderFullNameRaw
	 * @param {string} sUid
	 */
	WebMailCacheStorage.prototype.addNewMessageCache = function (sFolderFullNameRaw, sUid)
	{
		this.oNewMessage[this.getMessageKey(sFolderFullNameRaw, sUid)] = true;
	};

	/**
	 * @param {string} sFolderFullNameRaw
	 * @param {string} sUid
	 */
	WebMailCacheStorage.prototype.hasNewMessageAndRemoveFromCache = function (sFolderFullNameRaw, sUid)
	{
		if (this.oNewMessage[this.getMessageKey(sFolderFullNameRaw, sUid)])
		{
			this.oNewMessage[this.getMessageKey(sFolderFullNameRaw, sUid)] = null;
			return true;
		}

		return false;
	};

	WebMailCacheStorage.prototype.clearNewMessageCache = function ()
	{
		this.oNewMessage = {};
	};

	/**
	 * @param {string} sFolderHash
	 * @return {string}
	 */
	WebMailCacheStorage.prototype.getFolderFullNameRaw = function (sFolderHash)
	{
		return '' !== sFolderHash && this.oFoldersNamesCache[sFolderHash] ? this.oFoldersNamesCache[sFolderHash] : '';
	};

	/**
	 * @param {string} sFolderHash
	 * @param {string} sFolderFullNameRaw
	 */
	WebMailCacheStorage.prototype.setFolderFullNameRaw = function (sFolderHash, sFolderFullNameRaw)
	{
		this.oFoldersNamesCache[sFolderHash] = sFolderFullNameRaw;
	};

	/**
	 * @param {string} sFolderFullNameRaw
	 * @return {string}
	 */
	WebMailCacheStorage.prototype.getFolderHash = function (sFolderFullNameRaw)
	{
		return '' !== sFolderFullNameRaw && this.oFolderHashCache[sFolderFullNameRaw] ? this.oFolderHashCache[sFolderFullNameRaw] : '';
	};

	/**
	 * @param {string} sFolderFullNameRaw
	 * @param {string} sFolderHash
	 */
	WebMailCacheStorage.prototype.setFolderHash = function (sFolderFullNameRaw, sFolderHash)
	{
		this.oFolderHashCache[sFolderFullNameRaw] = sFolderHash;
	};

	/**
	 * @param {string} sFolderFullNameRaw
	 * @return {string}
	 */
	WebMailCacheStorage.prototype.getFolderUidNext = function (sFolderFullNameRaw)
	{
		return '' !== sFolderFullNameRaw && this.oFolderUidNextCache[sFolderFullNameRaw] ? this.oFolderUidNextCache[sFolderFullNameRaw] : '';
	};

	/**
	 * @param {string} sFolderFullNameRaw
	 * @param {string} sUidNext
	 */
	WebMailCacheStorage.prototype.setFolderUidNext = function (sFolderFullNameRaw, sUidNext)
	{
		this.oFolderUidNextCache[sFolderFullNameRaw] = sUidNext;
	};

	/**
	 * @param {string} sFolderFullNameRaw
	 * @return {?FolderModel}
	 */
	WebMailCacheStorage.prototype.getFolderFromCacheList = function (sFolderFullNameRaw)
	{
		return '' !== sFolderFullNameRaw && this.oFoldersCache[sFolderFullNameRaw] ? this.oFoldersCache[sFolderFullNameRaw] : null;
	};

	/**
	 * @param {string} sFolderFullNameRaw
	 * @param {?FolderModel} oFolder
	 */
	WebMailCacheStorage.prototype.setFolderToCacheList = function (sFolderFullNameRaw, oFolder)
	{
		this.oFoldersCache[sFolderFullNameRaw] = oFolder;
	};

	/**
	 * @param {string} sFolderFullNameRaw
	 */
	WebMailCacheStorage.prototype.removeFolderFromCacheList = function (sFolderFullNameRaw)
	{
		this.setFolderToCacheList(sFolderFullNameRaw, null);
	};

	/**
	 * @param {string} sFolderFullName
	 * @param {string} sUid
	 * @return {?Array}
	 */
	WebMailCacheStorage.prototype.getMessageFlagsFromCache = function (sFolderFullName, sUid)
	{
		return this.oMessageFlagsCache[sFolderFullName] && this.oMessageFlagsCache[sFolderFullName][sUid] ?
			this.oMessageFlagsCache[sFolderFullName][sUid] : null;
	};

	/**
	 * @param {string} sFolderFullName
	 * @param {string} sUid
	 * @param {Array} aFlagsCache
	 */
	WebMailCacheStorage.prototype.setMessageFlagsToCache = function (sFolderFullName, sUid, aFlagsCache)
	{
		if (!this.oMessageFlagsCache[sFolderFullName])
		{
			this.oMessageFlagsCache[sFolderFullName] = {};
		}

		this.oMessageFlagsCache[sFolderFullName][sUid] = aFlagsCache;
	};

	/**
	 * @param {string} sFolderFullName
	 */
	WebMailCacheStorage.prototype.clearMessageFlagsFromCacheByFolder = function (sFolderFullName)
	{
		this.oMessageFlagsCache[sFolderFullName] = {};
	};

	/**
	 * @param {(MessageModel|null)} oMessage
	 */
	WebMailCacheStorage.prototype.initMessageFlagsFromCache = function (oMessage)
	{
		if (oMessage)
		{
			var
				self = this,
				aFlags = this.getMessageFlagsFromCache(oMessage.folderFullNameRaw, oMessage.uid),
				mUnseenSubUid = null,
				mFlaggedSubUid = null
			;

			if (aFlags && 0 < aFlags.length)
			{
				oMessage.unseen(!!aFlags[0]);
				oMessage.flagged(!!aFlags[1]);
				oMessage.answered(!!aFlags[2]);
				oMessage.forwarded(!!aFlags[3]);
				oMessage.isReadReceipt(!!aFlags[4]);
			}

			if (0 < oMessage.threads().length)
			{
				mUnseenSubUid = _.find(oMessage.threads(), function (iSubUid) {
					var aFlags = self.getMessageFlagsFromCache(oMessage.folderFullNameRaw, iSubUid);
					return aFlags && 0 < aFlags.length && !!aFlags[0];
				});

				mFlaggedSubUid = _.find(oMessage.threads(), function (iSubUid) {
					var aFlags = self.getMessageFlagsFromCache(oMessage.folderFullNameRaw, iSubUid);
					return aFlags && 0 < aFlags.length && !!aFlags[1];
				});

				oMessage.hasUnseenSubMessage(mUnseenSubUid && 0 < Utils.pInt(mUnseenSubUid));
				oMessage.hasFlaggedSubMessage(mFlaggedSubUid && 0 < Utils.pInt(mFlaggedSubUid));
			}
		}
	};

	/**
	 * @param {(MessageModel|null)} oMessage
	 */
	WebMailCacheStorage.prototype.storeMessageFlagsToCache = function (oMessage)
	{
		if (oMessage)
		{
			this.setMessageFlagsToCache(
				oMessage.folderFullNameRaw,
				oMessage.uid,
				[oMessage.unseen(), oMessage.flagged(), oMessage.answered(), oMessage.forwarded(), oMessage.isReadReceipt()]
			);
		}
	};
	/**
	 * @param {string} sFolder
	 * @param {string} sUid
	 * @param {Array} aFlags
	 */
	WebMailCacheStorage.prototype.storeMessageFlagsToCacheByFolderAndUid = function (sFolder, sUid, aFlags)
	{
		if (Utils.isArray(aFlags) && 0 < aFlags.length)
		{
			this.setMessageFlagsToCache(sFolder, sUid, aFlags);
		}
	};

	module.exports = new WebMailCacheStorage();

}(module));
},{"../Common/Enums.js":5,"../Common/LinkBuilder.js":7,"../Common/Utils.js":9,"../External/underscore.js":24,"../RL.js":32}],41:[function(require,module,exports){
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */

(function (module) {

	'use strict';

	var
		window = require('../External/window.js'),
		$ = require('../External/jquery.js'),
		_ = require('../External/underscore.js'),
		ko = require('../External/ko.js'),
		moment = require('../External/moment.js'),
		$div = require('../External/$div.js'),
		NotificationClass = require('../External/NotificationClass.js'),
		
		Consts = require('../Common/Consts.js'),
		Enums = require('../Common/Enums.js'),
		Globals = require('../Common/Globals.js'),
		Utils = require('../Common/Utils.js'),
		LinkBuilder = require('../Common/LinkBuilder.js'),

		Cache = require('../Storages/WebMailCacheStorage.js'),
		Remote = require('../Storages/WebMailAjaxRemoteStorage.js'),
		
		kn = require('../Knoin/Knoin.js'),

		MessageModel = require('../Models/MessageModel.js'),

		LocalStorage = require('./LocalStorage.js'),
		AbstractData = require('./AbstractData.js')
	;

	/**
	 * @constructor
	 * @extends AbstractData
	 */
	function WebMailDataStorage()
	{
		AbstractData.call(this);

		var
			fRemoveSystemFolderType = function (observable) {
				return function () {
					var oFolder = Cache.getFolderFromCacheList(observable()); // TODO cjs
					if (oFolder)
					{
						oFolder.type(Enums.FolderType.User);
					}
				};
			},
			fSetSystemFolderType = function (iType) {
				return function (sValue) {
					var oFolder = Cache.getFolderFromCacheList(sValue); // TODO cjs
					if (oFolder)
					{
						oFolder.type(iType);
					}
				};
			}
		;

		this.devEmail = '';
		this.devPassword = '';

		this.accountEmail = ko.observable('');
		this.accountIncLogin = ko.observable('');
		this.accountOutLogin = ko.observable('');
		this.projectHash = ko.observable('');
		this.threading = ko.observable(false);

		this.lastFoldersHash = '';
		this.remoteSuggestions = false;

		// system folders
		this.sentFolder = ko.observable('');
		this.draftFolder = ko.observable('');
		this.spamFolder = ko.observable('');
		this.trashFolder = ko.observable('');
		this.archiveFolder = ko.observable('');

		this.sentFolder.subscribe(fRemoveSystemFolderType(this.sentFolder), this, 'beforeChange');
		this.draftFolder.subscribe(fRemoveSystemFolderType(this.draftFolder), this, 'beforeChange');
		this.spamFolder.subscribe(fRemoveSystemFolderType(this.spamFolder), this, 'beforeChange');
		this.trashFolder.subscribe(fRemoveSystemFolderType(this.trashFolder), this, 'beforeChange');
		this.archiveFolder.subscribe(fRemoveSystemFolderType(this.archiveFolder), this, 'beforeChange');

		this.sentFolder.subscribe(fSetSystemFolderType(Enums.FolderType.SentItems), this);
		this.draftFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Draft), this);
		this.spamFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Spam), this);
		this.trashFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Trash), this);
		this.archiveFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Archive), this);

		this.draftFolderNotEnabled = ko.computed(function () {
			return '' === this.draftFolder() || Consts.Values.UnuseOptionValue === this.draftFolder();
		}, this);

		// personal
		this.displayName = ko.observable('');
		this.signature = ko.observable('');
		this.signatureToAll = ko.observable(false);
		this.replyTo = ko.observable('');

		// security
		this.enableTwoFactor = ko.observable(false);

		// accounts
		this.accounts = ko.observableArray([]);
		this.accountsLoading = ko.observable(false).extend({'throttle': 100});

		// identities
		this.defaultIdentityID = ko.observable('');
		this.identities = ko.observableArray([]);
		this.identitiesLoading = ko.observable(false).extend({'throttle': 100});

		// contacts
		this.contactTags = ko.observableArray([]);
		this.contacts = ko.observableArray([]);
		this.contacts.loading = ko.observable(false).extend({'throttle': 200});
		this.contacts.importing = ko.observable(false).extend({'throttle': 200});
		this.contacts.syncing = ko.observable(false).extend({'throttle': 200});
		this.contacts.exportingVcf = ko.observable(false).extend({'throttle': 200});
		this.contacts.exportingCsv = ko.observable(false).extend({'throttle': 200});

		this.allowContactsSync = ko.observable(false);
		this.enableContactsSync = ko.observable(false);
		this.contactsSyncUrl = ko.observable('');
		this.contactsSyncUser = ko.observable('');
		this.contactsSyncPass = ko.observable('');

		this.allowContactsSync = ko.observable(!!RL.settingsGet('ContactsSyncIsAllowed')); // TODO cjs
		this.enableContactsSync = ko.observable(!!RL.settingsGet('EnableContactsSync'));
		this.contactsSyncUrl = ko.observable(RL.settingsGet('ContactsSyncUrl'));
		this.contactsSyncUser = ko.observable(RL.settingsGet('ContactsSyncUser'));
		this.contactsSyncPass = ko.observable(RL.settingsGet('ContactsSyncPassword'));

		// folders
		this.namespace = '';
		this.folderList = ko.observableArray([]);
		this.folderList.focused = ko.observable(false);

		this.foldersListError = ko.observable('');

		this.foldersLoading = ko.observable(false);
		this.foldersCreating = ko.observable(false);
		this.foldersDeleting = ko.observable(false);
		this.foldersRenaming = ko.observable(false);

		this.foldersChanging = ko.computed(function () {
			var
				bLoading = this.foldersLoading(),
				bCreating = this.foldersCreating(),
				bDeleting = this.foldersDeleting(),
				bRenaming = this.foldersRenaming()
			;
			return bLoading || bCreating || bDeleting || bRenaming;
		}, this);

		this.foldersInboxUnreadCount = ko.observable(0);

		this.currentFolder = ko.observable(null).extend({'toggleSubscribe': [null,
			function (oPrev) {
				if (oPrev)
				{
					oPrev.selected(false);
				}
			}, function (oNext) {
				if (oNext)
				{
					oNext.selected(true);
				}
			}
		]});

		this.currentFolderFullNameRaw = ko.computed(function () {
			return this.currentFolder() ? this.currentFolder().fullNameRaw : '';
		}, this);

		this.currentFolderFullName = ko.computed(function () {
			return this.currentFolder() ? this.currentFolder().fullName : '';
		}, this);

		this.currentFolderFullNameHash = ko.computed(function () {
			return this.currentFolder() ? this.currentFolder().fullNameHash : '';
		}, this);

		this.currentFolderName = ko.computed(function () {
			return this.currentFolder() ? this.currentFolder().name() : '';
		}, this);

		this.folderListSystemNames = ko.computed(function () {

			var
				aList = ['INBOX'],
				aFolders = this.folderList(),
				sSentFolder = this.sentFolder(),
				sDraftFolder = this.draftFolder(),
				sSpamFolder = this.spamFolder(),
				sTrashFolder = this.trashFolder(),
				sArchiveFolder = this.archiveFolder()
			;

			if (Utils.isArray(aFolders) && 0 < aFolders.length)
			{
				if ('' !== sSentFolder && Consts.Values.UnuseOptionValue !== sSentFolder)
				{
					aList.push(sSentFolder);
				}
				if ('' !== sDraftFolder && Consts.Values.UnuseOptionValue !== sDraftFolder)
				{
					aList.push(sDraftFolder);
				}
				if ('' !== sSpamFolder && Consts.Values.UnuseOptionValue !== sSpamFolder)
				{
					aList.push(sSpamFolder);
				}
				if ('' !== sTrashFolder && Consts.Values.UnuseOptionValue !== sTrashFolder)
				{
					aList.push(sTrashFolder);
				}
				if ('' !== sArchiveFolder && Consts.Values.UnuseOptionValue !== sArchiveFolder)
				{
					aList.push(sArchiveFolder);
				}
			}

			return aList;

		}, this);

		this.folderListSystem = ko.computed(function () {
			return _.compact(_.map(this.folderListSystemNames(), function (sName) {
				return Cache.getFolderFromCacheList(sName); // TODO cjs
			}));
		}, this);

		this.folderMenuForMove = ko.computed(function () {
			return RL.folderListOptionsBuilder(this.folderListSystem(), this.folderList(), [// TODO cjs
				this.currentFolderFullNameRaw()
			], null, null, null, null, function (oItem) {
				return oItem ? oItem.localName() : '';
			});
		}, this);

		// message list
		this.staticMessageList = [];

		this.messageList = ko.observableArray([]).extend({'rateLimit': 0});

		this.messageListCount = ko.observable(0);
		this.messageListSearch = ko.observable('');
		this.messageListPage = ko.observable(1);

		this.messageListThreadFolder = ko.observable('');
		this.messageListThreadUids = ko.observableArray([]);

		this.messageListThreadFolder.subscribe(function () {
			this.messageListThreadUids([]);
		}, this);

		this.messageListEndFolder = ko.observable('');
		this.messageListEndSearch = ko.observable('');
		this.messageListEndPage = ko.observable(1);

		this.messageListEndHash = ko.computed(function () {
			return this.messageListEndFolder() + '|' + this.messageListEndSearch() + '|' + this.messageListEndPage();
		}, this);

		this.messageListPageCount = ko.computed(function () {
			var iPage = window.Math.ceil(this.messageListCount() / this.messagesPerPage());
			return 0 >= iPage ? 1 : iPage;
		}, this);

		this.mainMessageListSearch = ko.computed({
			'read': this.messageListSearch,
			'write': function (sValue) {
				kn.setHash(LinkBuilder.mailBox( // TODO cjs
					this.currentFolderFullNameHash(), 1, Utils.trim(sValue.toString())
				));
			},
			'owner': this
		});

		this.messageListError = ko.observable('');

		this.messageListLoading = ko.observable(false);
		this.messageListIsNotCompleted = ko.observable(false);
		this.messageListCompleteLoadingThrottle = ko.observable(false).extend({'throttle': 200});

		this.messageListCompleteLoading = ko.computed(function () {
			var
				bOne = this.messageListLoading(),
				bTwo = this.messageListIsNotCompleted()
			;
			return bOne || bTwo;
		}, this);

		this.messageListCompleteLoading.subscribe(function (bValue) {
			this.messageListCompleteLoadingThrottle(bValue);
		}, this);

		this.messageList.subscribe(_.debounce(function (aList) {
			_.each(aList, function (oItem) {
				if (oItem.newForAnimation())
				{
					oItem.newForAnimation(false);
				}
			});
		}, 500));

		// message preview
		this.staticMessageList = new MessageModel();// TODO cjs
		this.message = ko.observable(null);
		this.messageLoading = ko.observable(false);
		this.messageLoadingThrottle = ko.observable(false).extend({'throttle': 50});

		this.message.focused = ko.observable(false);

		this.message.subscribe(function (oMessage) {
			if (!oMessage)
			{
				this.message.focused(false);
				this.messageFullScreenMode(false);
				this.hideMessageBodies();

				if (Enums.Layout.NoPreview === RL.data().layout() &&// TODO cjs
					-1 < window.location.hash.indexOf('message-preview'))
				{
					RL.historyBack();// TODO cjs
				}
			}
			else if (Enums.Layout.NoPreview === this.layout())
			{
				this.message.focused(true);
			}
		}, this);

		this.message.focused.subscribe(function (bValue) {
			if (bValue)
			{
				this.folderList.focused(false);
				this.keyScope(Enums.KeyState.MessageView);
			}
			else if (Enums.KeyState.MessageView === RL.data().keyScope())// TODO cjs
			{
				if (Enums.Layout.NoPreview === RL.data().layout() && this.message())// TODO cjs
				{
					this.keyScope(Enums.KeyState.MessageView);
				}
				else
				{
					this.keyScope(Enums.KeyState.MessageList);
				}
			}
		}, this);

		this.folderList.focused.subscribe(function (bValue) {
			if (bValue)
			{
				RL.data().keyScope(Enums.KeyState.FolderList);// TODO cjs
			}
			else if (Enums.KeyState.FolderList === RL.data().keyScope())// TODO cjs
			{
				RL.data().keyScope(Enums.KeyState.MessageList);// TODO cjs
			}
		});

		this.messageLoading.subscribe(function (bValue) {
			this.messageLoadingThrottle(bValue);
		}, this);

		this.messageFullScreenMode = ko.observable(false);

		this.messageError = ko.observable('');

		this.messagesBodiesDom = ko.observable(null);

		this.messagesBodiesDom.subscribe(function (oDom) {
			if (oDom && !(oDom instanceof $))
			{
				this.messagesBodiesDom($(oDom));
			}
		}, this);

		this.messageActiveDom = ko.observable(null);

		this.isMessageSelected = ko.computed(function () {
			return null !== this.message();
		}, this);

		this.currentMessage = ko.observable(null);

		this.messageListChecked = ko.computed(function () {
			return _.filter(this.messageList(), function (oItem) {
				return oItem.checked();
			});
		}, this).extend({'rateLimit': 0});

		this.hasCheckedMessages = ko.computed(function () {
			return 0 < this.messageListChecked().length;
		}, this).extend({'rateLimit': 0});

		this.messageListCheckedOrSelected = ko.computed(function () {

			var
				aChecked = this.messageListChecked(),
				oSelectedMessage = this.currentMessage()
			;

			return _.union(aChecked, oSelectedMessage ? [oSelectedMessage] : []);

		}, this);

		this.messageListCheckedOrSelectedUidsWithSubMails = ko.computed(function () {
			var aList = [];
			_.each(this.messageListCheckedOrSelected(), function (oMessage) {
				if (oMessage)
				{
					aList.push(oMessage.uid);
					if (0 < oMessage.threadsLen() && 0 === oMessage.parentUid() && oMessage.lastInCollapsedThread())
					{
						aList = _.union(aList, oMessage.threads());
					}
				}
			});
			return aList;
		}, this);

		// quota
		this.userQuota = ko.observable(0);
		this.userUsageSize = ko.observable(0);
		this.userUsageProc = ko.computed(function () {

			var
				iQuota = this.userQuota(),
				iUsed = this.userUsageSize()
			;

			return 0 < iQuota ? window.Math.ceil((iUsed / iQuota) * 100) : 0;

		}, this);

		// other
		this.capaOpenPGP = ko.observable(false);
		this.openpgpkeys = ko.observableArray([]);
		this.openpgpKeyring = null;

		this.openpgpkeysPublic = this.openpgpkeys.filter(function (oItem) {
			return !!(oItem && !oItem.isPrivate);
		});

		this.openpgpkeysPrivate = this.openpgpkeys.filter(function (oItem) {
			return !!(oItem && oItem.isPrivate);
		});

		// google
		this.googleActions = ko.observable(false);
		this.googleLoggined = ko.observable(false);
		this.googleUserName = ko.observable('');

		// facebook
		this.facebookActions = ko.observable(false);
		this.facebookLoggined = ko.observable(false);
		this.facebookUserName = ko.observable('');

		// twitter
		this.twitterActions = ko.observable(false);
		this.twitterLoggined = ko.observable(false);
		this.twitterUserName = ko.observable('');

		this.customThemeType = ko.observable(Enums.CustomThemeType.Light);

		this.purgeMessageBodyCacheThrottle = _.throttle(this.purgeMessageBodyCache, 1000 * 30);
	}

	_.extend(WebMailDataStorage.prototype, AbstractData.prototype);

	WebMailDataStorage.prototype.purgeMessageBodyCache = function()
	{
		var
			iCount = 0,
			oMessagesBodiesDom = null,
			iEnd = Globals.iMessageBodyCacheCount - Consts.Values.MessageBodyCacheLimit
		;

		if (0 < iEnd)
		{
			oMessagesBodiesDom = this.messagesBodiesDom();
			if (oMessagesBodiesDom)
			{
				oMessagesBodiesDom.find('.rl-cache-class').each(function () {
					var oItem = $(this);
					if (iEnd > oItem.data('rl-cache-count'))
					{
						oItem.addClass('rl-cache-purge');
						iCount++;
					}
				});

				if (0 < iCount)
				{
					_.delay(function () {
						oMessagesBodiesDom.find('.rl-cache-purge').remove();
					}, 300);
				}
			}
		}
	};

	WebMailDataStorage.prototype.populateDataOnStart = function()
	{
		AbstractData.prototype.populateDataOnStart.call(this);

		this.accountEmail(RL.settingsGet('Email'));// TODO cjs
		this.accountIncLogin(RL.settingsGet('IncLogin'));
		this.accountOutLogin(RL.settingsGet('OutLogin'));
		this.projectHash(RL.settingsGet('ProjectHash'));

		this.defaultIdentityID(RL.settingsGet('DefaultIdentityID'));

		this.displayName(RL.settingsGet('DisplayName'));
		this.replyTo(RL.settingsGet('ReplyTo'));
		this.signature(RL.settingsGet('Signature'));
		this.signatureToAll(!!RL.settingsGet('SignatureToAll'));
		this.enableTwoFactor(!!RL.settingsGet('EnableTwoFactor'));

		this.lastFoldersHash = LocalStorage.get(Enums.ClientSideKeyName.FoldersLashHash) || '';

		this.remoteSuggestions = !!RL.settingsGet('RemoteSuggestions');

		this.devEmail = RL.settingsGet('DevEmail');
		this.devPassword = RL.settingsGet('DevPassword');
	};

	WebMailDataStorage.prototype.initUidNextAndNewMessages = function (sFolder, sUidNext, aNewMessages)
	{
		if ('INBOX' === sFolder && Utils.isNormal(sUidNext) && sUidNext !== '')
		{
			if (Utils.isArray(aNewMessages) && 0 < aNewMessages.length)
			{
				var
					iIndex = 0,
					iLen = aNewMessages.length,
					fNotificationHelper = function (sImageSrc, sTitle, sText)
					{
						var oNotification = null;
						if (NotificationClass && RL.data().useDesktopNotifications())
						{
							oNotification = new NotificationClass(sTitle, {
								'body': sText,
								'icon': sImageSrc
							});

							if (oNotification)
							{
								if (oNotification.show)
								{
									oNotification.show();
								}

								window.setTimeout((function (oLocalNotifications) {
									return function () {
										if (oLocalNotifications.cancel)
										{
											oLocalNotifications.cancel();
										}
										else if (oLocalNotifications.close)
										{
											oLocalNotifications.close();
										}
									};
								}(oNotification)), 7000);
							}
						}
					}
				;

				_.each(aNewMessages, function (oItem) {
					Cache.addNewMessageCache(sFolder, oItem.Uid);
				});

				if (3 < iLen)
				{
					fNotificationHelper(
						LinkBuilder.notificationMailIcon(),
						RL.data().accountEmail(),
						Utils.i18n('MESSAGE_LIST/NEW_MESSAGE_NOTIFICATION', {
							'COUNT': iLen
						})
					);
				}
				else
				{
					for (; iIndex < iLen; iIndex++)
					{
						fNotificationHelper(
							LinkBuilder.notificationMailIcon(),
							MessageModel.emailsToLine(MessageModel.initEmailsFromJson(aNewMessages[iIndex].From), false),
							aNewMessages[iIndex].Subject
						);
					}
				}
			}

			Cache.setFolderUidNext(sFolder, sUidNext);
		}
	};

	/**
	 * @param {string} sNamespace
	 * @param {Array} aFolders
	 * @return {Array}
	 */
	WebMailDataStorage.prototype.folderResponseParseRec = function (sNamespace, aFolders)
	{
		var
			iIndex = 0,
			iLen = 0,
			oFolder = null,
			oCacheFolder = null,
			sFolderFullNameRaw = '',
			aSubFolders = [],
			aList = []
		;

		for (iIndex = 0, iLen = aFolders.length; iIndex < iLen; iIndex++)
		{
			oFolder = aFolders[iIndex];
			if (oFolder)
			{
				sFolderFullNameRaw = oFolder.FullNameRaw;

				oCacheFolder = Cache.getFolderFromCacheList(sFolderFullNameRaw);// TODO cjs
				if (!oCacheFolder)
				{
					oCacheFolder = FolderModel.newInstanceFromJson(oFolder);// TODO cjs
					if (oCacheFolder)
					{
						Cache.setFolderToCacheList(sFolderFullNameRaw, oCacheFolder);// TODO cjs
						Cache.setFolderFullNameRaw(oCacheFolder.fullNameHash, sFolderFullNameRaw);// TODO cjs
					}
				}

				if (oCacheFolder)
				{
					oCacheFolder.collapsed(!Utils.isFolderExpanded(oCacheFolder.fullNameHash));

					if (oFolder.Extended)
					{
						if (oFolder.Extended.Hash)
						{
							Cache.setFolderHash(oCacheFolder.fullNameRaw, oFolder.Extended.Hash);// TODO cjs
						}

						if (Utils.isNormal(oFolder.Extended.MessageCount))
						{
							oCacheFolder.messageCountAll(oFolder.Extended.MessageCount);
						}

						if (Utils.isNormal(oFolder.Extended.MessageUnseenCount))
						{
							oCacheFolder.messageCountUnread(oFolder.Extended.MessageUnseenCount);
						}
					}

					aSubFolders = oFolder['SubFolders'];
					if (aSubFolders && 'Collection/FolderCollection' === aSubFolders['@Object'] &&
						aSubFolders['@Collection'] && Utils.isArray(aSubFolders['@Collection']))
					{
						oCacheFolder.subFolders(
							this.folderResponseParseRec(sNamespace, aSubFolders['@Collection']));
					}

					aList.push(oCacheFolder);
				}
			}
		}

		return aList;
	};

	/**
	 * @param {*} oData
	 */
	WebMailDataStorage.prototype.setFolders = function (oData)
	{
		var
			aList = [],
			bUpdate = false,
			oRLData = RL.data(),// TODO cjs
			fNormalizeFolder = function (sFolderFullNameRaw) {
				return ('' === sFolderFullNameRaw || Consts.Values.UnuseOptionValue === sFolderFullNameRaw ||
					null !== Cache.getFolderFromCacheList(sFolderFullNameRaw)) ? sFolderFullNameRaw : '';// TODO cjs
			}
		;

		if (oData && oData.Result && 'Collection/FolderCollection' === oData.Result['@Object'] &&
			oData.Result['@Collection'] && Utils.isArray(oData.Result['@Collection']))
		{
			if (!Utils.isUnd(oData.Result.Namespace))
			{
				oRLData.namespace = oData.Result.Namespace;
			}

			this.threading(!!RL.settingsGet('UseImapThread') && oData.Result.IsThreadsSupported && true);// TODO cjs

			aList = this.folderResponseParseRec(oRLData.namespace, oData.Result['@Collection']);
			oRLData.folderList(aList);

			// TODO cjs
			if (oData.Result['SystemFolders'] &&
				'' === '' + RL.settingsGet('SentFolder') + RL.settingsGet('DraftFolder') +
				RL.settingsGet('SpamFolder') + RL.settingsGet('TrashFolder') + RL.settingsGet('ArchiveFolder') +
				RL.settingsGet('NullFolder'))
			{
				// TODO Magic Numbers
				RL.settingsSet('SentFolder', oData.Result['SystemFolders'][2] || null);
				RL.settingsSet('DraftFolder', oData.Result['SystemFolders'][3] || null);
				RL.settingsSet('SpamFolder', oData.Result['SystemFolders'][4] || null);
				RL.settingsSet('TrashFolder', oData.Result['SystemFolders'][5] || null);
				RL.settingsSet('ArchiveFolder', oData.Result['SystemFolders'][12] || null);

				bUpdate = true;
			}

			// TODO cjs
			oRLData.sentFolder(fNormalizeFolder(RL.settingsGet('SentFolder')));
			oRLData.draftFolder(fNormalizeFolder(RL.settingsGet('DraftFolder')));
			oRLData.spamFolder(fNormalizeFolder(RL.settingsGet('SpamFolder')));
			oRLData.trashFolder(fNormalizeFolder(RL.settingsGet('TrashFolder')));
			oRLData.archiveFolder(fNormalizeFolder(RL.settingsGet('ArchiveFolder')));

			if (bUpdate)
			{
				Remote.saveSystemFolders(Utils.emptyFunction, {
					'SentFolder': oRLData.sentFolder(),
					'DraftFolder': oRLData.draftFolder(),
					'SpamFolder': oRLData.spamFolder(),
					'TrashFolder': oRLData.trashFolder(),
					'ArchiveFolder': oRLData.archiveFolder(),
					'NullFolder': 'NullFolder'
				});
			}

			LocalStorage.set(Enums.ClientSideKeyName.FoldersLashHash, oData.Result.FoldersHash);
		}
	};

	WebMailDataStorage.prototype.hideMessageBodies = function ()
	{
		var oMessagesBodiesDom = this.messagesBodiesDom();
		if (oMessagesBodiesDom)
		{
			oMessagesBodiesDom.find('.b-text-part').hide();
		}
	};

	/**
	 * @param {boolean=} bBoot = false
	 * @returns {Array}
	 */
	WebMailDataStorage.prototype.getNextFolderNames = function (bBoot)
	{
		bBoot = Utils.isUnd(bBoot) ? false : !!bBoot;

		var
			aResult = [],
			iLimit = 10,
			iUtc = moment().unix(),
			iTimeout = iUtc - 60 * 5,
			aTimeouts = [],
			fSearchFunction = function (aList) {
				_.each(aList, function (oFolder) {
					if (oFolder && 'INBOX' !== oFolder.fullNameRaw &&
						oFolder.selectable && oFolder.existen &&
						iTimeout > oFolder.interval &&
						(!bBoot || oFolder.subScribed()))
					{
						aTimeouts.push([oFolder.interval, oFolder.fullNameRaw]);
					}

					if (oFolder && 0 < oFolder.subFolders().length)
					{
						fSearchFunction(oFolder.subFolders());
					}
				});
			}
		;

		fSearchFunction(this.folderList());

		aTimeouts.sort(function(a, b) {
			if (a[0] < b[0])
			{
				return -1;
			}
			else if (a[0] > b[0])
			{
				return 1;
			}

			return 0;
		});

		_.find(aTimeouts, function (aItem) {
			var oFolder = Cache.getFolderFromCacheList(aItem[1]);// TODO cjs
			if (oFolder)
			{
				oFolder.interval = iUtc;
				aResult.push(aItem[1]);
			}

			return iLimit <= aResult.length;
		});

		return _.uniq(aResult);
	};

	/**
	 * @param {string} sFromFolderFullNameRaw
	 * @param {Array} aUidForRemove
	 * @param {string=} sToFolderFullNameRaw = ''
	 * @param {bCopy=} bCopy = false
	 */
	WebMailDataStorage.prototype.removeMessagesFromList = function (
		sFromFolderFullNameRaw, aUidForRemove, sToFolderFullNameRaw, bCopy)
	{
		sToFolderFullNameRaw = Utils.isNormal(sToFolderFullNameRaw) ? sToFolderFullNameRaw : '';
		bCopy = Utils.isUnd(bCopy) ? false : !!bCopy;

		aUidForRemove = _.map(aUidForRemove, function (mValue) {
			return Utils.pInt(mValue);
		});

		var
			iUnseenCount = 0,
			oData = RL.data(),// TODO cjs
			aMessageList = oData.messageList(),
			oFromFolder = Cache.getFolderFromCacheList(sFromFolderFullNameRaw),
			oToFolder = '' === sToFolderFullNameRaw ? null : Cache.getFolderFromCacheList(sToFolderFullNameRaw || ''),
			sCurrentFolderFullNameRaw = oData.currentFolderFullNameRaw(),
			oCurrentMessage = oData.message(),
			aMessages = sCurrentFolderFullNameRaw === sFromFolderFullNameRaw ? _.filter(aMessageList, function (oMessage) {
				return oMessage && -1 < Utils.inArray(Utils.pInt(oMessage.uid), aUidForRemove);
			}) : []
		;

		_.each(aMessages, function (oMessage) {
			if (oMessage && oMessage.unseen())
			{
				iUnseenCount++;
			}
		});

		if (oFromFolder && !bCopy)
		{
			oFromFolder.messageCountAll(0 <= oFromFolder.messageCountAll() - aUidForRemove.length ?
				oFromFolder.messageCountAll() - aUidForRemove.length : 0);

			if (0 < iUnseenCount)
			{
				oFromFolder.messageCountUnread(0 <= oFromFolder.messageCountUnread() - iUnseenCount ?
					oFromFolder.messageCountUnread() - iUnseenCount : 0);
			}
		}

		if (oToFolder)
		{
			oToFolder.messageCountAll(oToFolder.messageCountAll() + aUidForRemove.length);
			if (0 < iUnseenCount)
			{
				oToFolder.messageCountUnread(oToFolder.messageCountUnread() + iUnseenCount);
			}

			oToFolder.actionBlink(true);
		}

		if (0 < aMessages.length)
		{
			if (bCopy)
			{
				_.each(aMessages, function (oMessage) {
					oMessage.checked(false);
				});
			}
			else
			{
				oData.messageListIsNotCompleted(true);

				_.each(aMessages, function (oMessage) {
					if (oCurrentMessage && oCurrentMessage.hash === oMessage.hash)
					{
						oCurrentMessage = null;
						oData.message(null);
					}

					oMessage.deleted(true);
				});

				_.delay(function () {
					_.each(aMessages, function (oMessage) {
						oData.messageList.remove(oMessage);
					});
				}, 400);
			}
		}

		if ('' !== sFromFolderFullNameRaw)
		{
			Cache.setFolderHash(sFromFolderFullNameRaw, '');
		}

		if ('' !== sToFolderFullNameRaw)
		{
			Cache.setFolderHash(sToFolderFullNameRaw, '');
		}
	};

	WebMailDataStorage.prototype.setMessage = function (oData, bCached)
	{
		var
			bIsHtml = false,
			bHasExternals = false,
			bHasInternals = false,
			oBody = null,
			oTextBody = null,
			sId = '',
			sResultHtml = '',
			bPgpSigned = false,
			bPgpEncrypted = false,
			oMessagesBodiesDom = this.messagesBodiesDom(),
			oMessage = this.message()
		;

		if (oData && oMessage && oData.Result && 'Object/Message' === oData.Result['@Object'] &&
			oMessage.folderFullNameRaw === oData.Result.Folder && oMessage.uid === oData.Result.Uid)
		{
			this.messageError('');

			oMessage.initUpdateByMessageJson(oData.Result);
			Cache.addRequestedMessage(oMessage.folderFullNameRaw, oMessage.uid);// TODO cjs

			if (!bCached)
			{
				oMessage.initFlagsByJson(oData.Result);
			}

			oMessagesBodiesDom = oMessagesBodiesDom && oMessagesBodiesDom[0] ? oMessagesBodiesDom : null;
			if (oMessagesBodiesDom)
			{
				sId = 'rl-mgs-' + oMessage.hash.replace(/[^a-zA-Z0-9]/g, '');
				oTextBody = oMessagesBodiesDom.find('#' + sId);
				if (!oTextBody || !oTextBody[0])
				{
					bHasExternals = !!oData.Result.HasExternals;
					bHasInternals = !!oData.Result.HasInternals;

					oBody = $('
').hide().addClass('rl-cache-class'); oBody.data('rl-cache-count', ++Globals.iMessageBodyCacheCount); if (Utils.isNormal(oData.Result.Html) && '' !== oData.Result.Html) { bIsHtml = true; sResultHtml = oData.Result.Html.toString(); } else if (Utils.isNormal(oData.Result.Plain) && '' !== oData.Result.Plain) { bIsHtml = false; sResultHtml = Utils.plainToHtml(oData.Result.Plain.toString(), false); if ((oMessage.isPgpSigned() || oMessage.isPgpEncrypted()) && RL.data().capaOpenPGP()) { oMessage.plainRaw = Utils.pString(oData.Result.Plain); bPgpEncrypted = /---BEGIN PGP MESSAGE---/.test(oMessage.plainRaw); if (!bPgpEncrypted) { bPgpSigned = /-----BEGIN PGP SIGNED MESSAGE-----/.test(oMessage.plainRaw) && /-----BEGIN PGP SIGNATURE-----/.test(oMessage.plainRaw); } $div.empty(); if (bPgpSigned && oMessage.isPgpSigned()) { sResultHtml = $div.append( $('
').text(oMessage.plainRaw)
									).html()
								;
							}
							else if (bPgpEncrypted && oMessage.isPgpEncrypted())
							{
								sResultHtml =
									$div.append(
										$('
').text(oMessage.plainRaw)
									).html()
								;
							}

							$div.empty();

							oMessage.isPgpSigned(bPgpSigned);
							oMessage.isPgpEncrypted(bPgpEncrypted);
						}
					}
					else
					{
						bIsHtml = false;
					}

					oBody
						.html(Utils.linkify(sResultHtml))
						.addClass('b-text-part ' + (bIsHtml ? 'html' : 'plain'))
					;

					oMessage.isHtml(!!bIsHtml);
					oMessage.hasImages(!!bHasExternals);
					oMessage.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.None);
					oMessage.pgpSignedVerifyUser('');

					oMessage.body = oBody;
					if (oMessage.body)
					{
						oMessagesBodiesDom.append(oMessage.body);
					}

					oMessage.storeDataToDom();

					if (bHasInternals)
					{
						oMessage.showInternalImages(true);
					}

					if (oMessage.hasImages() && this.showImages())
					{
						oMessage.showExternalImages(true);
					}

					this.purgeMessageBodyCacheThrottle();
				}
				else
				{
					oMessage.body = oTextBody;
					if (oMessage.body)
					{
						oMessage.body.data('rl-cache-count', ++Globals.iMessageBodyCacheCount);
						oMessage.fetchDataToDom();
					}
				}

				this.messageActiveDom(oMessage.body);

				this.hideMessageBodies();
				oMessage.body.show();

				if (oBody)
				{
					Utils.initBlockquoteSwitcher(oBody);
				}
			}

			Cache.initMessageFlagsFromCache(oMessage);
			if (oMessage.unseen())
			{
				RL.setMessageSeen(oMessage);
			}

			Utils.windowResize();
		}
	};

	/**
	 * @param {Array} aList
	 * @returns {string}
	 */
	WebMailDataStorage.prototype.calculateMessageListHash = function (aList)
	{
		return _.map(aList, function (oMessage) {
			return '' + oMessage.hash + '_' + oMessage.threadsLen() + '_' + oMessage.flagHash();
		}).join('|');
	};

	WebMailDataStorage.prototype.setMessageList = function (oData, bCached)
	{
		if (oData && oData.Result && 'Collection/MessageCollection' === oData.Result['@Object'] &&
			oData.Result['@Collection'] && Utils.isArray(oData.Result['@Collection']))
		{
			var
				oRainLoopData = RL.data(),
				mLastCollapsedThreadUids = null,
				iIndex = 0,
				iLen = 0,
				iCount = 0,
				iOffset = 0,
				aList = [],
				iUtc = moment().unix(),
				aStaticList = oRainLoopData.staticMessageList,
				oJsonMessage = null,
				oMessage = null,
				oFolder = null,
				iNewCount = 0,
				bUnreadCountChange = false
			;

			iCount = Utils.pInt(oData.Result.MessageResultCount);
			iOffset = Utils.pInt(oData.Result.Offset);

			if (Utils.isNonEmptyArray(oData.Result.LastCollapsedThreadUids))
			{
				mLastCollapsedThreadUids = oData.Result.LastCollapsedThreadUids;
			}

			oFolder = Cache.getFolderFromCacheList(
				Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : '');

			if (oFolder && !bCached)
			{
				oFolder.interval = iUtc;

				Cache.setFolderHash(oData.Result.Folder, oData.Result.FolderHash);

				if (Utils.isNormal(oData.Result.MessageCount))
				{
					oFolder.messageCountAll(oData.Result.MessageCount);
				}

				if (Utils.isNormal(oData.Result.MessageUnseenCount))
				{
					if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oData.Result.MessageUnseenCount))
					{
						bUnreadCountChange = true;
					}

					oFolder.messageCountUnread(oData.Result.MessageUnseenCount);
				}

				this.initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages);
			}

			if (bUnreadCountChange && oFolder)
			{
				Cache.clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw);
			}

			for (iIndex = 0, iLen = oData.Result['@Collection'].length; iIndex < iLen; iIndex++)
			{
				oJsonMessage = oData.Result['@Collection'][iIndex];
				if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object'])
				{
					oMessage = aStaticList[iIndex];
					if (!oMessage || !oMessage.initByJson(oJsonMessage))
					{
						oMessage = MessageModel.newInstanceFromJson(oJsonMessage);
					}

					if (oMessage)
					{
						if (Cache.hasNewMessageAndRemoveFromCache(oMessage.folderFullNameRaw, oMessage.uid) && 5 >= iNewCount)
						{
							iNewCount++;
							oMessage.newForAnimation(true);
						}

						oMessage.deleted(false);

						if (bCached)
						{
							Cache.initMessageFlagsFromCache(oMessage);
						}
						else
						{
							Cache.storeMessageFlagsToCache(oMessage);
						}

						oMessage.lastInCollapsedThread(mLastCollapsedThreadUids && -1 < Utils.inArray(Utils.pInt(oMessage.uid), mLastCollapsedThreadUids) ? true : false);

						aList.push(oMessage);
					}
				}
			}

			oRainLoopData.messageListCount(iCount);
			oRainLoopData.messageListSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : '');
			oRainLoopData.messageListPage(Math.ceil((iOffset / oRainLoopData.messagesPerPage()) + 1));
			oRainLoopData.messageListEndFolder(Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : '');
			oRainLoopData.messageListEndSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : '');
			oRainLoopData.messageListEndPage(oRainLoopData.messageListPage());

			oRainLoopData.messageList(aList);
			oRainLoopData.messageListIsNotCompleted(false);

			if (aStaticList.length < aList.length)
			{
				oRainLoopData.staticMessageList = aList;
			}

			Cache.clearNewMessageCache();

			if (oFolder && (bCached || bUnreadCountChange || RL.data().useThreads()))
			{
				RL.folderInformation(oFolder.fullNameRaw, aList);
			}
		}
		else
		{
			RL.data().messageListCount(0);
			RL.data().messageList([]);
			RL.data().messageListError(Utils.getNotification(
				oData && oData.ErrorCode ? oData.ErrorCode : Enums.Notification.CantGetMessageList
			));
		}
	};

	WebMailDataStorage.prototype.findPublicKeyByHex = function (sHash)
	{
		return _.find(this.openpgpkeysPublic(), function (oItem) {
			return oItem && sHash === oItem.id;
		});
	};

	WebMailDataStorage.prototype.findPublicKeysByEmail = function (sEmail)
	{
		return _.compact(_.map(this.openpgpkeysPublic(), function (oItem) {

			var oKey = null;
			if (oItem && sEmail === oItem.email)
			{
				try
				{
					oKey = window.openpgp.key.readArmored(oItem.armor);
					if (oKey && !oKey.err && oKey.keys && oKey.keys[0])
					{
						return oKey.keys[0];
					}
				}
				catch (e) {}
			}

			return null;

		}));
	};

	/**
	 * @param {string} sEmail
	 * @param {string=} sPassword
	 * @returns {?}
	 */
	WebMailDataStorage.prototype.findPrivateKeyByEmail = function (sEmail, sPassword)
	{
		var
			oPrivateKey = null,
			oKey = _.find(this.openpgpkeysPrivate(), function (oItem) {
				return oItem && sEmail === oItem.email;
			})
		;

		if (oKey)
		{
			try
			{
				oPrivateKey = window.openpgp.key.readArmored(oKey.armor);
				if (oPrivateKey && !oPrivateKey.err && oPrivateKey.keys && oPrivateKey.keys[0])
				{
					oPrivateKey = oPrivateKey.keys[0];
					oPrivateKey.decrypt(Utils.pString(sPassword));
				}
				else
				{
					oPrivateKey = null;
				}
			}
			catch (e)
			{
				oPrivateKey = null;
			}
		}

		return oPrivateKey;
	};

	/**
	 * @param {string=} sPassword
	 * @returns {?}
	 */
	WebMailDataStorage.prototype.findSelfPrivateKey = function (sPassword)
	{
		return this.findPrivateKeyByEmail(this.accountEmail(), sPassword);
	};

	module.exports = new WebMailDataStorage();

}(module));

},{"../Common/Consts.js":4,"../Common/Enums.js":5,"../Common/Globals.js":6,"../Common/LinkBuilder.js":7,"../Common/Utils.js":9,"../External/$div.js":10,"../External/NotificationClass.js":16,"../External/jquery.js":19,"../External/ko.js":21,"../External/moment.js":22,"../External/underscore.js":24,"../External/window.js":25,"../Knoin/Knoin.js":26,"../Models/MessageModel.js":31,"../Storages/WebMailAjaxRemoteStorage.js":39,"../Storages/WebMailCacheStorage.js":40,"./AbstractData.js":35,"./LocalStorage.js":36}],42:[function(require,module,exports){
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */

(function (module) {

	'use strict';

	var
		ko = require('../../External/ko.js'),
		key = require('../../External/key.js'),
		Enums = require('../../Common/Enums.js'),
		Utils = require('../../Common/Utils.js'),
		kn = require('../../Knoin/Knoin.js'),
		KnoinAbstractViewModel = require('../../Knoin/KnoinAbstractViewModel.js')
	;

	/**
	 * @constructor
	 * @extends KnoinAbstractViewModel
	 */
	function PopupsAskViewModel()
	{
		KnoinAbstractViewModel.call(this, 'Popups', 'PopupsAsk');

		this.askDesc = ko.observable('');
		this.yesButton = ko.observable('');
		this.noButton = ko.observable('');

		this.yesFocus = ko.observable(false);
		this.noFocus = ko.observable(false);

		this.fYesAction = null;
		this.fNoAction = null;

		this.bDisabeCloseOnEsc = true;
		this.sDefaultKeyScope = Enums.KeyState.PopupAsk;

		kn.constructorEnd(this);
	}

	kn.extendAsViewModel('PopupsAskViewModel', PopupsAskViewModel);

	PopupsAskViewModel.prototype.clearPopup = function ()
	{
		this.askDesc('');
		this.yesButton(Utils.i18n('POPUPS_ASK/BUTTON_YES'));
		this.noButton(Utils.i18n('POPUPS_ASK/BUTTON_NO'));

		this.yesFocus(false);
		this.noFocus(false);

		this.fYesAction = null;
		this.fNoAction = null;
	};

	PopupsAskViewModel.prototype.yesClick = function ()
	{
		this.cancelCommand();

		if (Utils.isFunc(this.fYesAction))
		{
			this.fYesAction.call(null);
		}
	};

	PopupsAskViewModel.prototype.noClick = function ()
	{
		this.cancelCommand();

		if (Utils.isFunc(this.fNoAction))
		{
			this.fNoAction.call(null);
		}
	};

	/**
	 * @param {string} sAskDesc
	 * @param {Function=} fYesFunc
	 * @param {Function=} fNoFunc
	 * @param {string=} sYesButton
	 * @param {string=} sNoButton
	 */
	PopupsAskViewModel.prototype.onShow = function (sAskDesc, fYesFunc, fNoFunc, sYesButton, sNoButton)
	{
		this.clearPopup();

		this.fYesAction = fYesFunc || null;
		this.fNoAction = fNoFunc || null;

		this.askDesc(sAskDesc || '');
		if (sYesButton)
		{
			this.yesButton(sYesButton);
		}

		if (sYesButton)
		{
			this.yesButton(sNoButton);
		}
	};

	PopupsAskViewModel.prototype.onFocus = function ()
	{
		this.yesFocus(true);
	};

	PopupsAskViewModel.prototype.onBuild = function ()
	{
		key('tab, shift+tab, right, left', Enums.KeyState.PopupAsk, _.bind(function () {
			if (this.yesFocus())
			{
				this.noFocus(true);
			}
			else
			{
				this.yesFocus(true);
			}
			return false;
		}, this));

		key('esc', Enums.KeyState.PopupAsk, _.bind(function () {
			this.noClick();
			return false;
		}, this));
	};

	module.exports = new PopupsAskViewModel();

}(module));
},{"../../Common/Enums.js":5,"../../Common/Utils.js":9,"../../External/key.js":20,"../../External/ko.js":21,"../../Knoin/Knoin.js":26,"../../Knoin/KnoinAbstractViewModel.js":28}]},{},[1]);