gXbfB#) ۻbis_IIߪ ۻbis_IIߪ ۻbis_IIߪ ۻbis_II4&D.5;Aϳކ:}Wۻp%8gXL×uG5L@?ss\,fa\eChɛ+MMX,-\_[6Eq_uC^avh ->]+/Wg׿>|"d2D^1=]mwgFN5K]OElf5F \wgFN5K]OwgFN5K]OwgFN5K]O[_׮|S: jJˮ9AywgFN5K]OwgFN5K]OwgFN5K]OPjqWMJAz%EHOn"nwgFN5K]OwgFN5K]OQ+RŞԲ&M.x ۻbis_IIߪ ۻbis_IIߪ ۻbis_II߄}BkH11%|t 8"/"#lHA k`^RnL |4^%EVhDSUG ) )M@l]8NjB+CWWmC3m;&Q|$sI~$FƂpֵ.' +&;|A`gY"$Ct -rG#mGrAG-zv,{{Tm.b,: ]bUGDtH2 eb <5~NeӤ7F`tt/MC7ޱXe>>|J0fb; o.)ܟnrXn2eyy<%'54Va`daz'|rضt/ #5B[$FIЀ.=)CSZ̸kDȲ7!v"WeMw%h+׋4<^&FL2ɱT>jI%I."L;F RcFh ;Q\Zw`$~se<"s}D={ҽm<;WfY҅: MClRnň2HMa-y j3dBH<dE9.D;*B#Ip{A,R>*&ϱQ{Wv&m:j^ά& Ț@rW;Ca@ {+uM.ٌ]eSEǶmPŬ|kWVaś5=+e4oɄx.s/*(Z54">~>G]}ݙ<,4LpjTy{e0ʰ-ll$ MZWs -ih\>cM&&u:Ed6a3 ;ĻQ<h6|˭B1LJ37.X }0R`:3Y h8 <`XRG\!C(_'jOzN3U%u (A <~P"IkݯFTPƟ7 PhmY{= b;  MsԚ:bHs z7)j3sYkLN@n I&)s8}rDZ=4. S;%m+]ko{\+,<)`ľG|Ô#q0z4Uaxg wh<> >d &gAY󂴚/ W*S[\S ѽ"eA!@򯶂iv/5\) 8| fm勇S 'Dp}Z?L30ӨhyЉ-x&YFd|ݹẁG5X Qp{ "ih%%3IZ_MGROO!\;3e1RL9 +׋o|RfJlvJ:Q#yp Ÿ3Z4`N_wm~BnrUܪLnYF+Ѐ&q2Jmko0%k:uѭm(v GQV֯.6鋶Ɨ(nFA.~M,$>艚tQVV-1EͺKur,wr4ȅ%biE!!UO0^7lXT?Q2Žb|hrȓMM*SnVd G0,+)݀o ND,<]!x;HHq,3(7ALb=gة`rce# G[iMM3gd`OahҙTˆЂ=PLq :Zv=;MDhI3 !Zer%ƣb8HN]g-ޗ'tM7r$#9) n0LGlI!ʧy|p9#vR'HQۿ <vBUNyHOݟ2Jڧ1o~t-Y1Et)Gk-W8fEKVE E(j \%,?|SB7WMx*Zc~JE#DZm;g 7- 413^3dq[d5⋐-ñꖽp*L)❰ȺyH h $maxlength) { if ($ending) { return mb_substr($str, 0, $maxlength) . $placeholder; } $placeholder_length = mb_strlen($placeholder); $first_part_length = floor(($maxlength - $placeholder_length)/2); $second_starting_location = $length - $maxlength + $first_part_length + $placeholder_length; $prefix = mb_substr($str, 0, $first_part_length); $suffix = mb_substr($str, $second_starting_location); $str = $prefix . $placeholder . $suffix; } return $str; } /** * Get all keys from array (recursive). * * @param array $array Input array * * @return array List of array keys */ function array_keys_recursive($array) { $keys = []; if (!empty($array) && is_array($array)) { foreach ($array as $key => $child) { $keys[] = $key; foreach (array_keys_recursive($child) as $val) { $keys[] = $val; } } } return $keys; } /** * Get first element from an array * * @param array $array Input array * * @return mixed First element if found, Null otherwise */ function array_first($array) { if (is_array($array)) { reset($array); foreach ($array as $element) { return $element; } } } /** * Remove all non-ascii and non-word chars except ., -, _ * * @param string $str A string * @param bool $css_id The result may be used as CSS identifier * @param string $replace_with Replacement character * * @return string Clean string */ function asciiwords($str, $css_id = false, $replace_with = '') { $allowed = 'a-z0-9\_\-' . (!$css_id ? '\.' : ''); return preg_replace("/[^$allowed]+/i", $replace_with, (string) $str); } /** * Check if a string contains only ascii characters * * @param string $str String to check * @param bool $control_chars Includes control characters * * @return bool True if the string contains ASCII-only, False otherwise */ function is_ascii($str, $control_chars = true) { $regexp = $control_chars ? '/[^\x00-\x7F]/' : '/[^\x20-\x7E]/'; return preg_match($regexp, (string) $str) ? false : true; } /** * Compose a valid representation of name and e-mail address * * @param string $email E-mail address * @param string $name Person name * * @return string Formatted string */ function format_email_recipient($email, $name = '') { $email = trim($email); if ($name && $name != $email) { // Special chars as defined by RFC 822 need to in quoted string (or escaped). if (preg_match('/[\(\)\<\>\\\.\[\]@,;:"]/', $name)) { $name = '"'.addcslashes($name, '"').'"'; } return "$name <$email>"; } return $email; } /** * Format e-mail address * * @param string $email E-mail address * * @return string Formatted e-mail address */ function format_email($email) { $email = trim($email); $parts = explode('@', $email); $count = count($parts); if ($count > 1) { $parts[$count-1] = mb_strtolower($parts[$count-1]); $email = implode('@', $parts); } return $email; } /** * Fix version number so it can be used correctly in version_compare() * * @param string $version Version number string * * @param return Version number string */ function version_parse($version) { return str_replace( ['-stable', '-git'], ['.0', '.99'], $version ); } /** * Use PHP5 autoload for dynamic class loading * * @param string $classname Class name * * @return bool True when the class file has been found * * @todo Make Zend, PEAR etc play with this * @todo Make our classes conform to a more straight forward CS. */ function rcube_autoload($classname) { if (strpos($classname, 'rcube') === 0) { $classname = preg_replace('/^rcube_(cache|db|session|spellchecker)_/', '\\1/', $classname); $classname = 'Roundcube/' . $classname; } else if (strpos($classname, 'html_') === 0 || $classname === 'html') { $classname = 'Roundcube/html'; } else if (strpos($classname, 'Mail_') === 0) { $classname = 'Mail/' . substr($classname, 5); } else if (strpos($classname, 'Net_') === 0) { $classname = 'Net/' . substr($classname, 4); } else if (strpos($classname, 'Auth_') === 0) { $classname = 'Auth/' . substr($classname, 5); } // Translate PHP namespaces into directories, // i.e. use \Sabre\VObject; $vcf = VObject\Reader::read(...) // -> Sabre/VObject/Reader.php $classname = str_replace('\\', '/', $classname); if ($fp = @fopen("$classname.php", 'r', true)) { fclose($fp); include_once "$classname.php"; return true; } return false; }